luci-app-passwall: sync upstream

last commit: 469d747c10
This commit is contained in:
gitea-action 2024-12-19 14:30:21 +08:00
parent b53f44e7f1
commit f10bf9db48
40 changed files with 1572 additions and 1469 deletions

View File

@ -166,11 +166,11 @@ end
function get_now_use_node() function get_now_use_node()
local path = "/tmp/etc/passwall/acl/default" local path = "/tmp/etc/passwall/acl/default"
local e = {} local e = {}
local tcp_node = api.get_cache_var("GLOBAL_TCP_node") local tcp_node = api.get_cache_var("ACL_GLOBAL_TCP_node")
if tcp_node then if tcp_node then
e["TCP"] = tcp_node e["TCP"] = tcp_node
end end
local udp_node = api.get_cache_var("GLOBAL_UDP_node") local udp_node = api.get_cache_var("ACL_GLOBAL_UDP_node")
if udp_node then if udp_node then
e["UDP"] = udp_node e["UDP"] = udp_node
end end
@ -364,8 +364,8 @@ end
function clear_all_nodes() function clear_all_nodes()
uci:set(appname, '@global[0]', "enabled", "0") uci:set(appname, '@global[0]', "enabled", "0")
uci:set(appname, '@global[0]', "tcp_node", "nil") uci:delete(appname, '@global[0]', "tcp_node")
uci:set(appname, '@global[0]', "udp_node", "nil") uci:delete(appname, '@global[0]', "udp_node")
uci:foreach(appname, "socks", function(t) uci:foreach(appname, "socks", function(t)
uci:delete(appname, t[".name"]) uci:delete(appname, t[".name"])
uci:set_list(appname, t[".name"], "autoswitch_backup_node", {}) uci:set_list(appname, t[".name"], "autoswitch_backup_node", {})
@ -374,8 +374,8 @@ function clear_all_nodes()
uci:delete(appname, t[".name"]) uci:delete(appname, t[".name"])
end) end)
uci:foreach(appname, "acl_rule", function(t) uci:foreach(appname, "acl_rule", function(t)
uci:set(appname, t[".name"], "tcp_node", "nil") uci:delete(appname, t[".name"], "tcp_node")
uci:set(appname, t[".name"], "udp_node", "nil") uci:delete(appname, t[".name"], "udp_node")
end) end)
uci:foreach(appname, "nodes", function(node) uci:foreach(appname, "nodes", function(node)
uci:delete(appname, node['.name']) uci:delete(appname, node['.name'])
@ -388,11 +388,11 @@ end
function delete_select_nodes() function delete_select_nodes()
local ids = luci.http.formvalue("ids") local ids = luci.http.formvalue("ids")
string.gsub(ids, '[^' .. "," .. ']+', function(w) string.gsub(ids, '[^' .. "," .. ']+', function(w)
if (uci:get(appname, "@global[0]", "tcp_node") or "nil") == w then if (uci:get(appname, "@global[0]", "tcp_node") or "") == w then
uci:set(appname, '@global[0]', "tcp_node", "nil") uci:delete(appname, '@global[0]', "tcp_node")
end end
if (uci:get(appname, "@global[0]", "udp_node") or "nil") == w then if (uci:get(appname, "@global[0]", "udp_node") or "") == w then
uci:set(appname, '@global[0]', "udp_node", "nil") uci:delete(appname, '@global[0]', "udp_node")
end end
uci:foreach(appname, "socks", function(t) uci:foreach(appname, "socks", function(t)
if t["node"] == w then if t["node"] == w then
@ -413,10 +413,10 @@ function delete_select_nodes()
end) end)
uci:foreach(appname, "acl_rule", function(t) uci:foreach(appname, "acl_rule", function(t)
if t["tcp_node"] == w then if t["tcp_node"] == w then
uci:set(appname, t[".name"], "tcp_node", "nil") uci:delete(appname, t[".name"], "tcp_node")
end end
if t["udp_node"] == w then if t["udp_node"] == w then
uci:set(appname, t[".name"], "udp_node", "nil") uci:delete(appname, t[".name"], "udp_node")
end end
end) end)
uci:foreach(appname, "nodes", function(t) uci:foreach(appname, "nodes", function(t)

View File

@ -52,7 +52,7 @@ o.rmempty = false
---- Remarks ---- Remarks
o = s:option(Value, "remarks", translate("Remarks")) o = s:option(Value, "remarks", translate("Remarks"))
o.default = arg[1] o.default = arg[1]
o.rmempty = true o.rmempty = false
o = s:option(ListValue, "interface", translate("Source Interface")) o = s:option(ListValue, "interface", translate("Source Interface"))
o:value("", translate("All")) o:value("", translate("All"))
@ -148,97 +148,117 @@ sources.write = dynamicList_write
---- TCP No Redir Ports ---- TCP No Redir Ports
local TCP_NO_REDIR_PORTS = uci:get(appname, "@global_forwarding[0]", "tcp_no_redir_ports") local TCP_NO_REDIR_PORTS = uci:get(appname, "@global_forwarding[0]", "tcp_no_redir_ports")
o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports")) o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports"))
o.default = "default" o:value("", translate("Use global config") .. "(" .. TCP_NO_REDIR_PORTS .. ")")
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o:value("default", translate("Use global config") .. "(" .. TCP_NO_REDIR_PORTS .. ")")
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o.validate = port_validate o.validate = port_validate
---- UDP No Redir Ports ---- UDP No Redir Ports
local UDP_NO_REDIR_PORTS = uci:get(appname, "@global_forwarding[0]", "udp_no_redir_ports") local UDP_NO_REDIR_PORTS = uci:get(appname, "@global_forwarding[0]", "udp_no_redir_ports")
o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"), o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"),
"<font color='red'>" .. translate( "<font color='red'>" ..
"Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") .. translate("Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") ..
"</font>") "</font>")
o.default = "default" o:value("", translate("Use global config") .. "(" .. UDP_NO_REDIR_PORTS .. ")")
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o:value("default", translate("Use global config") .. "(" .. UDP_NO_REDIR_PORTS .. ")")
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o.validate = port_validate o.validate = port_validate
o = s:option(DummyValue, "_hide_node_option", "")
o.template = "passwall/cbi/hidevalue"
o.value = "1"
o:depends({ tcp_no_redir_ports = "1:65535", udp_no_redir_ports = "1:65535" })
if TCP_NO_REDIR_PORTS == "1:65535" and UDP_NO_REDIR_PORTS == "1:65535" then
o:depends({ tcp_no_redir_ports = "", udp_no_redir_ports = "" })
end
o = s:option(Flag, "use_global_config", translatef("Use global config")) o = s:option(Flag, "use_global_config", translatef("Use global config"))
o.default = "0" o.default = "0"
o.rmempty = false o.rmempty = false
o:depends({ _hide_node_option = "1", ['!reverse'] = true })
tcp_node = s:option(ListValue, "tcp_node", "<a style='color: red'>" .. translate("TCP Node") .. "</a>") o = s:option(ListValue, "tcp_node", "<a style='color: red'>" .. translate("TCP Node") .. "</a>")
tcp_node.default = "" o.default = ""
tcp_node:value("", translate("Close")) o:depends({ _hide_node_option = false, use_global_config = false })
tcp_node:depends("use_global_config", false)
udp_node = s:option(ListValue, "udp_node", "<a style='color: red'>" .. translate("UDP Node") .. "</a>") o = s:option(DummyValue, "_tcp_node_bool", "")
udp_node.default = "" o.template = "passwall/cbi/hidevalue"
udp_node:value("", translate("Close")) o.value = "1"
udp_node:value("tcp", translate("Same as the tcp node")) o:depends({ tcp_node = "", ['!reverse'] = true })
udp_node:depends({ tcp_node = "", ['!reverse'] = true })
o = s:option(ListValue, "udp_node", "<a style='color: red'>" .. translate("UDP Node") .. "</a>")
o.default = ""
o:value("", translate("Close"))
o:value("tcp", translate("Same as the tcp node"))
o:depends({ _tcp_node_bool = "1" })
for k, v in pairs(nodes_table) do for k, v in pairs(nodes_table) do
tcp_node:value(v.id, v["remark"]) s.fields["tcp_node"]:value(v.id, v["remark"])
udp_node:value(v.id, v["remark"]) s.fields["udp_node"]:value(v.id, v["remark"])
end end
o = s:option(DummyValue, "_udp_node_bool", "")
o.template = "passwall/cbi/hidevalue"
o.value = "1"
o:depends({ udp_node = "", ['!reverse'] = true })
---- TCP Proxy Drop Ports ---- TCP Proxy Drop Ports
local TCP_PROXY_DROP_PORTS = uci:get(appname, "@global_forwarding[0]", "tcp_proxy_drop_ports") local TCP_PROXY_DROP_PORTS = uci:get(appname, "@global_forwarding[0]", "tcp_proxy_drop_ports")
o = s:option(Value, "tcp_proxy_drop_ports", translate("TCP Proxy Drop Ports")) o = s:option(Value, "tcp_proxy_drop_ports", translate("TCP Proxy Drop Ports"))
o.default = "default" o:value("", translate("Use global config") .. "(" .. TCP_PROXY_DROP_PORTS .. ")")
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o:value("default", translate("Use global config") .. "(" .. TCP_PROXY_DROP_PORTS .. ")")
o.validate = port_validate o.validate = port_validate
o:depends({ use_global_config = true })
o:depends({ _tcp_node_bool = "1" })
---- UDP Proxy Drop Ports ---- UDP Proxy Drop Ports
local UDP_PROXY_DROP_PORTS = uci:get(appname, "@global_forwarding[0]", "udp_proxy_drop_ports") local UDP_PROXY_DROP_PORTS = uci:get(appname, "@global_forwarding[0]", "udp_proxy_drop_ports")
o = s:option(Value, "udp_proxy_drop_ports", translate("UDP Proxy Drop Ports")) o = s:option(Value, "udp_proxy_drop_ports", translate("UDP Proxy Drop Ports"))
o.default = "default" o:value("", translate("Use global config") .. "(" .. UDP_PROXY_DROP_PORTS .. ")")
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o:value("default", translate("Use global config") .. "(" .. UDP_PROXY_DROP_PORTS .. ")")
o:value("443", translate("QUIC")) o:value("443", translate("QUIC"))
o.validate = port_validate o.validate = port_validate
o:depends({ use_global_config = true })
o:depends({ _tcp_node_bool = "1" })
---- TCP Redir Ports ---- TCP Redir Ports
local TCP_REDIR_PORTS = uci:get(appname, "@global_forwarding[0]", "tcp_redir_ports") local TCP_REDIR_PORTS = uci:get(appname, "@global_forwarding[0]", "tcp_redir_ports")
o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports"), translatef("Only work with using the %s node.", "TCP")) o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports"), translatef("Only work with using the %s node.", "TCP"))
o.default = "default" o:value("", translate("Use global config") .. "(" .. TCP_REDIR_PORTS .. ")")
o:value("default", translate("Use global config") .. "(" .. TCP_REDIR_PORTS .. ")")
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o:value("80,443", "80,443") o:value("80,443", "80,443")
o:value("80:65535", "80 " .. translate("or more")) o:value("80:65535", "80 " .. translate("or more"))
o:value("1:443", "443 " .. translate("or less")) o:value("1:443", "443 " .. translate("or less"))
o.validate = port_validate o.validate = port_validate
o:depends({ use_global_config = true })
o:depends({ _tcp_node_bool = "1" })
---- UDP Redir Ports ---- UDP Redir Ports
local UDP_REDIR_PORTS = uci:get(appname, "@global_forwarding[0]", "udp_redir_ports") local UDP_REDIR_PORTS = uci:get(appname, "@global_forwarding[0]", "udp_redir_ports")
o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports"), translatef("Only work with using the %s node.", "UDP")) o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports"), translatef("Only work with using the %s node.", "UDP"))
o.default = "default" o:value("", translate("Use global config") .. "(" .. UDP_REDIR_PORTS .. ")")
o:value("default", translate("Use global config") .. "(" .. UDP_REDIR_PORTS .. ")")
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o:value("53", "53") o:value("53", "53")
o.validate = port_validate o.validate = port_validate
o:depends({ use_global_config = true })
o:depends({ _udp_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"
o:depends({ tcp_node = "", ['!reverse'] = true }) o:depends({ _tcp_node_bool = "1" })
o = s:option(Flag, "use_proxy_list", translatef("Use %s", translate("Proxy List"))) o = s:option(Flag, "use_proxy_list", translatef("Use %s", translate("Proxy List")))
o.default = "1" o.default = "1"
o:depends({ tcp_node = "", ['!reverse'] = true }) o:depends({ _tcp_node_bool = "1" })
o = s:option(Flag, "use_block_list", translatef("Use %s", translate("Block List"))) o = s:option(Flag, "use_block_list", translatef("Use %s", translate("Block List")))
o.default = "1" o.default = "1"
o:depends({ tcp_node = "", ['!reverse'] = true }) o:depends({ _tcp_node_bool = "1" })
if has_gfwlist then if has_gfwlist then
o = s:option(Flag, "use_gfw_list", translatef("Use %s", translate("GFW List"))) o = s:option(Flag, "use_gfw_list", translatef("Use %s", translate("GFW List")))
o.default = "1" o.default = "1"
o:depends({ tcp_node = "", ['!reverse'] = true }) o:depends({ _tcp_node_bool = "1" })
end end
if has_chnlist or has_chnroute then if has_chnlist or has_chnroute then
@ -247,36 +267,36 @@ if has_chnlist or has_chnroute then
o:value("direct", translate("Direct Connection")) o:value("direct", translate("Direct Connection"))
o:value("proxy", translate("Proxy")) o:value("proxy", translate("Proxy"))
o.default = "direct" o.default = "direct"
o:depends({ tcp_node = "", ['!reverse'] = true }) o:depends({ _tcp_node_bool = "1" })
end end
o = s:option(ListValue, "tcp_proxy_mode", "TCP " .. translate("Proxy Mode")) o = s:option(ListValue, "tcp_proxy_mode", "TCP " .. translate("Proxy Mode"))
o:value("disable", translate("No Proxy")) o:value("disable", translate("No Proxy"))
o:value("proxy", translate("Proxy")) o:value("proxy", translate("Proxy"))
o:depends({ tcp_node = "", ['!reverse'] = true }) o:depends({ _tcp_node_bool = "1" })
o = s:option(ListValue, "udp_proxy_mode", "UDP " .. translate("Proxy Mode")) o = s:option(ListValue, "udp_proxy_mode", "UDP " .. translate("Proxy Mode"))
o:value("disable", translate("No Proxy")) o:value("disable", translate("No Proxy"))
o:value("proxy", translate("Proxy")) o:value("proxy", translate("Proxy"))
o:depends({ udp_node = "", ['!reverse'] = true }) o:depends({ _udp_node_bool = "1" })
o = s:option(DummyValue, "switch_mode", " ") o = s:option(DummyValue, "switch_mode", " ")
o.template = appname .. "/global/proxy" o.template = appname .. "/global/proxy"
o:depends({ tcp_node = "", ['!reverse'] = true }) o:depends({ _tcp_node_bool = "1" })
---- DNS ---- DNS
o = s:option(ListValue, "dns_shunt", "DNS " .. translate("Shunt")) o = s:option(ListValue, "dns_shunt", "DNS " .. translate("Shunt"))
o:depends({ tcp_node = "", ['!reverse'] = true }) o:depends({ _tcp_node_bool = "1" })
o:value("dnsmasq", "Dnsmasq") o:value("dnsmasq", "Dnsmasq")
o:value("chinadns-ng", translate("ChinaDNS-NG (recommended)")) o:value("chinadns-ng", translate("ChinaDNS-NG (recommended)"))
o = s:option(Flag, "filter_proxy_ipv6", translate("Filter Proxy Host IPv6"), translate("Experimental feature.")) o = s:option(Flag, "filter_proxy_ipv6", translate("Filter Proxy Host IPv6"), translate("Experimental feature."))
o.default = "0" o.default = "0"
o:depends({ tcp_node = "", ['!reverse'] = true }) o:depends({ _tcp_node_bool = "1" })
---- DNS Forward Mode ---- DNS Forward Mode
o = s:option(ListValue, "dns_mode", translate("Filter Mode")) o = s:option(ListValue, "dns_mode", translate("Filter Mode"))
o:depends({ tcp_node = "", ['!reverse'] = true }) o:depends({ _tcp_node_bool = "1" })
if api.is_finded("dns2socks") then if api.is_finded("dns2socks") then
o:value("dns2socks", "dns2socks") o:value("dns2socks", "dns2socks")
end end

View File

@ -126,19 +126,19 @@ o = s:taboption("Main", Flag, "enabled", translate("Main switch"))
o.rmempty = false o.rmempty = false
---- TCP Node ---- TCP Node
tcp_node = s:taboption("Main", ListValue, "tcp_node", "<a style='color: red'>" .. translate("TCP Node") .. "</a>") o = s:taboption("Main", ListValue, "tcp_node", "<a style='color: red'>" .. translate("TCP Node") .. "</a>")
tcp_node:value("nil", translate("Close")) o:value("", translate("Close"))
---- UDP Node ---- UDP Node
udp_node = s:taboption("Main", ListValue, "udp_node", "<a style='color: red'>" .. translate("UDP Node") .. "</a>") o = s:taboption("Main", ListValue, "udp_node", "<a style='color: red'>" .. translate("UDP Node") .. "</a>")
udp_node:value("nil", translate("Close")) o:value("", translate("Close"))
udp_node:value("tcp", translate("Same as the tcp node")) o:value("tcp", translate("Same as the tcp node"))
-- 分流 -- 分流
if (has_singbox or has_xray) and #nodes_table > 0 then if (has_singbox or has_xray) and #nodes_table > 0 then
local function get_cfgvalue(shunt_node_id, option) local function get_cfgvalue(shunt_node_id, option)
return function(self, section) return function(self, section)
return m:get(shunt_node_id, option) or "nil" return m:get(shunt_node_id, option)
end end
end end
local function get_write(shunt_node_id, option) local function get_write(shunt_node_id, option)
@ -187,7 +187,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
if (has_singbox and has_xray) or (v.type == "sing-box" and not has_singbox) or (v.type == "Xray" and not has_xray) then 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) type:depends("tcp_node", v.id)
else else
type:depends("tcp_node", "hide") --不存在的依赖,即始终隐藏 type:depends("tcp_node", "__hide") --不存在的依赖,即始终隐藏
end end
uci:foreach(appname, "shunt_rules", function(e) uci:foreach(appname, "shunt_rules", function(e)
@ -198,7 +198,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
o.cfgvalue = get_cfgvalue(v.id, id) o.cfgvalue = get_cfgvalue(v.id, id)
o.write = get_write(v.id, id) o.write = get_write(v.id, id)
o:depends("tcp_node", v.id) o:depends("tcp_node", v.id)
o:value("nil", translate("Close")) o:value("", translate("Close"))
o:value("_default", translate("Default")) o:value("_default", translate("Default"))
o:value("_direct", translate("Direct Connection")) o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole")) o:value("_blackhole", translate("Blackhole"))
@ -206,9 +206,8 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
local pt = s:taboption("Main", ListValue, vid .. "-".. id .. "_proxy_tag", string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy"))) local pt = s:taboption("Main", ListValue, vid .. "-".. id .. "_proxy_tag", string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy")))
pt.cfgvalue = get_cfgvalue(v.id, id .. "_proxy_tag") pt.cfgvalue = get_cfgvalue(v.id, id .. "_proxy_tag")
pt.write = get_write(v.id, id .. "_proxy_tag") pt.write = get_write(v.id, id .. "_proxy_tag")
pt:value("nil", translate("Close")) pt:value("", translate("Close"))
pt:value("main", translate("Preproxy Node")) pt:value("main", translate("Preproxy Node"))
pt.default = "nil"
for k1, v1 in pairs(socks_list) do for k1, v1 in pairs(socks_list) do
o:value(v1.id, v1.remark) o:value(v1.id, v1.remark)
end end
@ -249,7 +248,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
o = s:taboption("Main", ListValue, vid .. "-" .. id, string.format('* <a style="color:red">%s</a>', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node.")) o = s:taboption("Main", ListValue, vid .. "-" .. id, string.format('* <a style="color:red">%s</a>', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node."))
o.cfgvalue = get_cfgvalue(v.id, id) o.cfgvalue = get_cfgvalue(v.id, id)
o.write = get_write(v.id, id) o.write = get_write(v.id, id)
o:value("nil", translate("Close")) o:value("", translate("Close"))
o:value("main", translate("Preproxy Node")) o:value("main", translate("Preproxy Node"))
for k1, v1 in pairs(normal_list) do for k1, v1 in pairs(normal_list) do
if v1.protocol ~= "_balancing" then if v1.protocol ~= "_balancing" then
@ -263,7 +262,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
tips.cfgvalue = function(t, n) tips.cfgvalue = function(t, n)
return string.format('<a style="color: red">%s</a>', translate("There are no available nodes, please add or subscribe nodes first.")) return string.format('<a style="color: red">%s</a>', translate("There are no available nodes, please add or subscribe nodes first."))
end end
tips:depends({ tcp_node = "nil", ["!reverse"] = true }) tips:depends({ tcp_node = "", ["!reverse"] = true })
for k, v in pairs(shunt_list) do for k, v in pairs(shunt_list) do
tips:depends("udp_node", v.id) tips:depends("udp_node", v.id)
end end
@ -273,36 +272,35 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
end end
end end
tcp_node_socks_port = s:taboption("Main", Value, "tcp_node_socks_port", translate("TCP Node") .. " Socks " .. translate("Listen Port")) o = s:taboption("Main", Value, "tcp_node_socks_port", translate("TCP Node") .. " Socks " .. translate("Listen Port"))
tcp_node_socks_port.default = 1070 o.default = 1070
tcp_node_socks_port.datatype = "port" o.datatype = "port"
tcp_node_socks_port:depends({ tcp_node = "nil", ["!reverse"] = true }) o:depends({ tcp_node = "", ["!reverse"] = true })
--[[ --[[
if has_singbox or has_xray then if has_singbox or has_xray then
tcp_node_http_port = s:taboption("Main", Value, "tcp_node_http_port", translate("TCP Node") .. " HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use")) o = s:taboption("Main", Value, "tcp_node_http_port", translate("TCP Node") .. " HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
tcp_node_http_port.default = 0 o.default = 0
tcp_node_http_port.datatype = "port" o.datatype = "port"
end end
]]-- ]]--
tcp_node_socks_bind_local = s:taboption("Main", Flag, "tcp_node_socks_bind_local", translate("TCP Node") .. " Socks " .. translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) o = s:taboption("Main", Flag, "tcp_node_socks_bind_local", translate("TCP Node") .. " Socks " .. translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
tcp_node_socks_bind_local.default = "1" o.default = "1"
tcp_node_socks_bind_local:depends({ tcp_node = "nil", ["!reverse"] = true }) o:depends({ tcp_node = "", ["!reverse"] = true })
s:tab("DNS", translate("DNS")) s:tab("DNS", translate("DNS"))
dns_shunt = s:taboption("DNS", ListValue, "dns_shunt", "DNS " .. translate("Shunt")) o = s:taboption("DNS", ListValue, "dns_shunt", "DNS " .. translate("Shunt"))
dns_shunt:value("dnsmasq", "Dnsmasq") o:value("dnsmasq", "Dnsmasq")
dns_shunt:value("chinadns-ng", translate("ChinaDNS-NG (recommended)")) o:value("chinadns-ng", translate("ChinaDNS-NG (recommended)"))
if api.is_finded("smartdns") then if api.is_finded("smartdns") then
dns_shunt:value("smartdns", "SmartDNS") o:value("smartdns", "SmartDNS")
group_domestic = s:taboption("DNS", Value, "group_domestic", translate("Domestic group name")) o = s:taboption("DNS", Value, "group_domestic", translate("Domestic group name"))
group_domestic.placeholder = "local" o.placeholder = "local"
group_domestic:depends("dns_shunt", "smartdns") o:depends("dns_shunt", "smartdns")
group_domestic.description = translate("You only need to configure domestic DNS packets in SmartDNS and set it redirect or as Dnsmasq upstream, and fill in the domestic DNS group name here.") o.description = translate("You only need to configure domestic DNS packets in SmartDNS and set it redirect or as Dnsmasq upstream, and fill in the domestic DNS group name here.")
end end
o = s:taboption("DNS", ListValue, "direct_dns_mode", translate("Direct DNS") .. " " .. translate("Request protocol")) o = s:taboption("DNS", ListValue, "direct_dns_mode", translate("Direct DNS") .. " " .. translate("Request protocol"))
o.default = ""
o:value("", translate("Auto")) o:value("", translate("Auto"))
o:value("udp", translatef("Requery DNS By %s", "UDP")) o:value("udp", translatef("Requery DNS By %s", "UDP"))
o:value("tcp", translatef("Requery DNS By %s", "TCP")) o:value("tcp", translatef("Requery DNS By %s", "TCP"))
@ -399,23 +397,23 @@ if api.is_finded("smartdns") then
end end
---- DNS Forward Mode ---- DNS Forward Mode
dns_mode = s:taboption("DNS", ListValue, "dns_mode", translate("Filter Mode")) o = s:taboption("DNS", ListValue, "dns_mode", translate("Filter Mode"))
dns_mode:value("udp", translatef("Requery DNS By %s", "UDP")) o:value("udp", translatef("Requery DNS By %s", "UDP"))
dns_mode:value("tcp", translatef("Requery DNS By %s", "TCP")) o:value("tcp", translatef("Requery DNS By %s", "TCP"))
if chinadns_tls == 0 then if chinadns_tls == 0 then
dns_mode:value("dot", translatef("Requery DNS By %s", "DoT")) o:value("dot", translatef("Requery DNS By %s", "DoT"))
end end
if api.is_finded("dns2socks") then if api.is_finded("dns2socks") then
dns_mode:value("dns2socks", "dns2socks") o:value("dns2socks", "dns2socks")
end end
if has_singbox then if has_singbox then
dns_mode:value("sing-box", "Sing-Box") o:value("sing-box", "Sing-Box")
end end
if has_xray then if has_xray then
dns_mode:value("xray", "Xray") o:value("xray", "Xray")
end end
if api.is_finded("smartdns") then if api.is_finded("smartdns") then
dns_mode:depends({ dns_shunt = "smartdns", ['!reverse'] = true }) o:depends({ dns_shunt = "smartdns", ['!reverse'] = true })
end end
o = s:taboption("DNS", ListValue, "xray_dns_mode", translate("Request protocol")) o = s:taboption("DNS", ListValue, "xray_dns_mode", translate("Request protocol"))
@ -426,7 +424,7 @@ o.cfgvalue = function(self, section)
return m:get(section, "v2ray_dns_mode") return m:get(section, "v2ray_dns_mode")
end end
o.write = function(self, section, value) o.write = function(self, section, value)
if dns_mode:formvalue(section) == "xray" then if s.fields["dns_mode"]:formvalue(section) == "xray" then
return m:set(section, "v2ray_dns_mode", value) return m:set(section, "v2ray_dns_mode", value)
end end
end end
@ -439,7 +437,7 @@ o.cfgvalue = function(self, section)
return m:get(section, "v2ray_dns_mode") return m:get(section, "v2ray_dns_mode")
end end
o.write = function(self, section, value) o.write = function(self, section, value)
if dns_mode:formvalue(section) == "sing-box" then if s.fields["dns_mode"]:formvalue(section) == "sing-box" then
return m:set(section, "v2ray_dns_mode", value) return m:set(section, "v2ray_dns_mode", value)
end end
end end
@ -524,9 +522,9 @@ o.default = "0"
o:depends({dns_mode = "sing-box", dns_shunt = "dnsmasq"}) o:depends({dns_mode = "sing-box", dns_shunt = "dnsmasq"})
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value and value == "1" then if value and value == "1" then
local _dns_mode = dns_mode:formvalue(t) local _dns_mode = s.fields["dns_mode"]:formvalue(t)
local _tcp_node = tcp_node:formvalue(t) local _tcp_node = s.fields["tcp_node"]:formvalue(t)
if _dns_mode and _tcp_node and _tcp_node ~= "nil" then if _dns_mode and _tcp_node then
if m:get(_tcp_node, "type"):lower() ~= _dns_mode then if m:get(_tcp_node, "type"):lower() ~= _dns_mode then
return nil, translatef("TCP node must be '%s' type to use FakeDNS.", _dns_mode) return nil, translatef("TCP node must be '%s' type to use FakeDNS.", _dns_mode)
end end
@ -603,16 +601,16 @@ if has_chnlist or has_chnroute then
end end
---- TCP Default Proxy Mode ---- TCP Default Proxy Mode
tcp_proxy_mode = s:taboption("Proxy", ListValue, "tcp_proxy_mode", "TCP " .. translate("Default Proxy Mode")) o = s:taboption("Proxy", ListValue, "tcp_proxy_mode", "TCP " .. translate("Default Proxy Mode"))
tcp_proxy_mode:value("disable", translate("No Proxy")) o:value("disable", translate("No Proxy"))
tcp_proxy_mode:value("proxy", translate("Proxy")) o:value("proxy", translate("Proxy"))
tcp_proxy_mode.default = "proxy" o.default = "proxy"
---- UDP Default Proxy Mode ---- UDP Default Proxy Mode
udp_proxy_mode = s:taboption("Proxy", ListValue, "udp_proxy_mode", "UDP " .. translate("Default Proxy Mode")) o = s:taboption("Proxy", ListValue, "udp_proxy_mode", "UDP " .. translate("Default Proxy Mode"))
udp_proxy_mode:value("disable", translate("No Proxy")) o:value("disable", translate("No Proxy"))
udp_proxy_mode:value("proxy", translate("Proxy")) o:value("proxy", translate("Proxy"))
udp_proxy_mode.default = "proxy" o.default = "proxy"
o = s:taboption("Proxy", DummyValue, "switch_mode", " ") o = s:taboption("Proxy", DummyValue, "switch_mode", " ")
o.template = appname .. "/global/proxy" o.template = appname .. "/global/proxy"
@ -640,20 +638,20 @@ o = s:taboption("log", Flag, "log_udp", translate("Enable") .. " " .. translatef
o.default = "1" o.default = "1"
o.rmempty = false o.rmempty = false
loglevel = s:taboption("log", ListValue, "loglevel", "Sing-Box/Xray " .. translate("Log Level")) o = s:taboption("log", ListValue, "loglevel", "Sing-Box/Xray " .. translate("Log Level"))
loglevel.default = "warning" o.default = "warning"
loglevel:value("debug") o:value("debug")
loglevel:value("info") o:value("info")
loglevel:value("warning") o:value("warning")
loglevel:value("error") o:value("error")
trojan_loglevel = s:taboption("log", ListValue, "trojan_loglevel", "Trojan " .. translate("Log Level")) o = s:taboption("log", ListValue, "trojan_loglevel", "Trojan " .. translate("Log Level"))
trojan_loglevel.default = "2" o.default = "2"
trojan_loglevel:value("0", "all") o:value("0", "all")
trojan_loglevel:value("1", "info") o:value("1", "info")
trojan_loglevel:value("2", "warn") o:value("2", "warn")
trojan_loglevel:value("3", "error") o:value("3", "error")
trojan_loglevel:value("4", "fatal") o:value("4", "fatal")
o = s:taboption("log", Flag, "advanced_log_feature", translate("Advanced log feature"), translate("For professionals only.")) o = s:taboption("log", Flag, "advanced_log_feature", translate("Advanced log feature"), translate("For professionals only."))
o.default = "0" o.default = "0"
@ -676,30 +674,30 @@ o.template = appname .. "/global/faq"
o = s:taboption("Main", Flag, "socks_enabled", "Socks " .. translate("Main switch")) o = s:taboption("Main", Flag, "socks_enabled", "Socks " .. translate("Main switch"))
o.rmempty = false o.rmempty = false
s = m:section(TypedSection, "socks", translate("Socks Config")) s2 = m:section(TypedSection, "socks", translate("Socks Config"))
s.template = "cbi/tblsection" s2.template = "cbi/tblsection"
s.anonymous = true s2.anonymous = true
s.addremove = true s2.addremove = true
s.extedit = api.url("socks_config", "%s") s2.extedit = api.url("socks_config", "%s")
function s.create(e, t) function s2.create(e, t)
local uuid = api.gen_short_uuid() local uuid = api.gen_short_uuid()
t = uuid t = uuid
TypedSection.create(e, t) TypedSection.create(e, t)
luci.http.redirect(e.extedit:format(t)) luci.http.redirect(e.extedit:format(t))
end end
o = s:option(DummyValue, "status", translate("Status")) o = s2:option(DummyValue, "status", translate("Status"))
o.rawhtml = true o.rawhtml = true
o.cfgvalue = function(t, n) o.cfgvalue = function(t, n)
return string.format('<div class="_status" socks_id="%s"></div>', n) return string.format('<div class="_status" socks_id="%s"></div>', n)
end end
---- Enable ---- Enable
o = s:option(Flag, "enabled", translate("Enable")) o = s2:option(Flag, "enabled", translate("Enable"))
o.default = 1 o.default = 1
o.rmempty = false o.rmempty = false
socks_node = s:option(ListValue, "node", translate("Socks Node")) o = s2:option(ListValue, "node", translate("Socks Node"))
local n = 1 local n = 1
uci:foreach(appname, "socks", function(s) uci:foreach(appname, "socks", function(s)
@ -709,26 +707,26 @@ uci:foreach(appname, "socks", function(s)
n = n + 1 n = n + 1
end) end)
o = s:option(Value, "port", "Socks " .. translate("Listen Port")) o = s2:option(Value, "port", "Socks " .. translate("Listen Port"))
o.default = n + 1080 o.default = n + 1080
o.datatype = "port" o.datatype = "port"
o.rmempty = false o.rmempty = false
if has_singbox or has_xray then if has_singbox or has_xray then
o = s:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use")) o = s2:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
o.default = 0 o.default = 0
o.datatype = "port" o.datatype = "port"
end end
for k, v in pairs(nodes_table) do for k, v in pairs(nodes_table) do
tcp_node:value(v.id, v["remark"]) s.fields["tcp_node"]:value(v.id, v["remark"])
udp_node:value(v.id, v["remark"]) s.fields["udp_node"]:value(v.id, v["remark"])
if v.type == "Socks" then if v.type == "Socks" then
if has_singbox or has_xray then if has_singbox or has_xray then
socks_node:value(v.id, v["remark"]) s2.fields["node"]:value(v.id, v["remark"])
end end
else else
socks_node:value(v.id, v["remark"]) s2.fields["node"]:value(v.id, v["remark"])
end end
end end

View File

@ -61,15 +61,15 @@ function s.remove(e, t)
end end
end) end)
TypedSection.remove(e, t) TypedSection.remove(e, t)
local new_node = "nil" local new_node = ""
local node0 = m:get("@nodes[0]") or nil local node0 = m:get("@nodes[0]") or nil
if node0 then if node0 then
new_node = node0[".name"] new_node = node0[".name"]
end end
if (m:get("@global[0]", "tcp_node") or "nil") == t then if (m:get("@global[0]", "tcp_node") or "") == t then
m:set('@global[0]', "tcp_node", new_node) m:set('@global[0]', "tcp_node", new_node)
end end
if (m:get("@global[0]", "udp_node") or "nil") == t then if (m:get("@global[0]", "udp_node") or "") == t then
m:set('@global[0]', "udp_node", new_node) m:set('@global[0]', "udp_node", new_node)
end end
end end

View File

@ -17,44 +17,44 @@ s = m:section(TypedSection, "global_delay", translate("Delay Settings"))
s.anonymous = true s.anonymous = true
s.addremove = false s.addremove = false
---- Delay Start
o = s:option(Value, "start_delay", translate("Delay Start"),
translate("Units:seconds"))
o.default = "1"
o.rmempty = true
---- Open and close Daemon ---- Open and close Daemon
o = s:option(Flag, "start_daemon", translate("Open and close Daemon")) o = s:option(Flag, "start_daemon", translate("Open and close Daemon"))
o.default = 1 o.default = 1
o.rmempty = false o.rmempty = false
--[[ ---- Delay Start
---- Open and close automatically o = s:option(Value, "start_delay", translate("Delay Start"), translate("Units:seconds"))
o = s:option(Flag, "auto_on", translate("Open and close automatically")) o.default = "1"
o.rmempty = true
for index, value in ipairs({"stop", "start", "restart"}) do
o = s:option(ListValue, value .. "_week_mode", translate(value .. " automatically mode"))
o:value("", translate("Disable"))
o:value(8, translate("Loop Mode"))
o:value(7, translate("Every day"))
o:value(1, translate("Every Monday"))
o:value(2, translate("Every Tuesday"))
o:value(3, translate("Every Wednesday"))
o:value(4, translate("Every Thursday"))
o:value(5, translate("Every Friday"))
o:value(6, translate("Every Saturday"))
o:value(0, translate("Every Sunday"))
o = s:option(ListValue, value .. "_time_mode", translate(value .. " Time(Every day)"))
for t = 0, 23 do o:value(t, t .. ":00") end
o.default = 0 o.default = 0
o.rmempty = false o:depends(value .. "_week_mode", "0")
o:depends(value .. "_week_mode", "1")
---- Automatically turn off time o:depends(value .. "_week_mode", "2")
o = s:option(ListValue, "time_off", translate("Automatically turn off time")) o:depends(value .. "_week_mode", "3")
o.default = nil o:depends(value .. "_week_mode", "4")
o:depends("auto_on", true) o:depends(value .. "_week_mode", "5")
o:value(nil, translate("Disable")) o:depends(value .. "_week_mode", "6")
for e = 0, 23 do o:value(e, e .. translate("oclock")) end o:depends(value .. "_week_mode", "7")
o = s:option(ListValue, value .. "_interval_mode", translate(value .. " Interval(Hour)"))
---- Automatically turn on time for t = 1, 24 do o:value(t, t .. " " .. translate("Hour")) end
o = s:option(ListValue, "time_on", translate("Automatically turn on time")) o.default = 2
o.default = nil o:depends(value .. "_week_mode", "8")
o:depends("auto_on", true) end
o:value(nil, translate("Disable"))
for e = 0, 23 do o:value(e, e .. translate("oclock")) end
---- Automatically restart time
o = s:option(ListValue, "time_restart", translate("Automatically restart time"))
o.default = nil
o:depends("auto_on", true)
o:value(nil, translate("Disable"))
for e = 0, 23 do o:value(e, e .. translate("oclock")) end
--]]
-- [[ Forwarding Settings ]]-- -- [[ Forwarding Settings ]]--
s = m:section(TypedSection, "global_forwarding", s = m:section(TypedSection, "global_forwarding",

View File

@ -10,7 +10,7 @@ local type_name = "Hysteria2"
local option_prefix = "hysteria2_" local option_prefix = "hysteria2_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -18,59 +18,59 @@ end
s.fields["type"]:value(type_name, "Hysteria2") s.fields["type"]:value(type_name, "Hysteria2")
o = s:option(ListValue, option_name("protocol"), translate("Protocol")) o = s:option(ListValue, _n("protocol"), translate("Protocol"))
o:value("udp", "UDP") o:value("udp", "UDP")
o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
o = s:option(Value, option_name("port"), translate("Port")) o = s:option(Value, _n("port"), translate("Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(Value, option_name("hop"), translate("Additional ports for hysteria hop")) o = s:option(Value, _n("hop"), translate("Additional ports for hysteria hop"))
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("obfs"), translate("Obfs Password")) o = s:option(Value, _n("obfs"), translate("Obfs Password"))
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("auth_password"), translate("Auth Password")) o = s:option(Value, _n("auth_password"), translate("Auth Password"))
o.password = true o.password = true
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Flag, option_name("fast_open"), translate("Fast Open")) o = s:option(Flag, _n("fast_open"), translate("Fast Open"))
o.default = "0" o.default = "0"
o = s:option(Value, option_name("tls_serverName"), translate("Domain")) o = s:option(Value, _n("tls_serverName"), translate("Domain"))
o = s:option(Flag, option_name("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped."))
o.default = "0" o.default = "0"
o = s:option(Value, option_name("tls_pinSHA256"), translate("PinSHA256"),translate("Certificate fingerprint")) o = s:option(Value, _n("tls_pinSHA256"), translate("PinSHA256"),translate("Certificate fingerprint"))
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("up_mbps"), translate("Max upload Mbps")) o = s:option(Value, _n("up_mbps"), translate("Max upload Mbps"))
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("down_mbps"), translate("Max download Mbps")) o = s:option(Value, _n("down_mbps"), translate("Max download Mbps"))
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)") o = s:option(Value, _n("hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("recv_window"), translate("QUIC stream receive window")) o = s:option(Value, _n("recv_window"), translate("QUIC stream receive window"))
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("recv_window_conn"), translate("QUIC connection receive window")) o = s:option(Value, _n("recv_window_conn"), translate("QUIC connection receive window"))
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("idle_timeout"), translate("Idle Timeout"), translate("Example:") .. "30s (4s-120s)") o = s:option(Value, _n("idle_timeout"), translate("Idle Timeout"), translate("Example:") .. "30s (4s-120s)")
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Flag, option_name("disable_mtu_discovery"), translate("Disable MTU detection")) o = s:option(Flag, _n("disable_mtu_discovery"), translate("Disable MTU detection"))
o.default = "0" o.default = "0"
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Flag, option_name("lazy_start"), translate("Lazy Start")) o = s:option(Flag, _n("lazy_start"), translate("Lazy Start"))
o.default = "0" o.default = "0"
o.rewrite_option = o.option o.rewrite_option = o.option

View File

@ -10,7 +10,7 @@ local type_name = "Naiveproxy"
local option_prefix = "naive_" local option_prefix = "naive_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -18,18 +18,18 @@ end
s.fields["type"]:value(type_name, translate("NaiveProxy")) s.fields["type"]:value(type_name, translate("NaiveProxy"))
o = s:option(ListValue, option_name("protocol"), translate("Protocol")) o = s:option(ListValue, _n("protocol"), translate("Protocol"))
o:value("https", translate("HTTPS")) o:value("https", translate("HTTPS"))
o:value("quic", translate("QUIC")) o:value("quic", translate("QUIC"))
o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
o = s:option(Value, option_name("port"), translate("Port")) o = s:option(Value, _n("port"), translate("Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(Value, option_name("username"), translate("Username")) o = s:option(Value, _n("username"), translate("Username"))
o = s:option(Value, option_name("password"), translate("Password")) o = s:option(Value, _n("password"), translate("Password"))
o.password = true o.password = true
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -14,7 +14,7 @@ local type_name = "Xray"
local option_prefix = "xray_" local option_prefix = "xray_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -33,7 +33,7 @@ local xray_version = api.get_app_version("xray")
s.fields["type"]:value(type_name, "Xray") s.fields["type"]:value(type_name, "Xray")
o = s:option(ListValue, option_name("protocol"), translate("Protocol")) o = s:option(ListValue, _n("protocol"), translate("Protocol"))
o:value("vmess", translate("Vmess")) o:value("vmess", translate("Vmess"))
o:value("vless", translate("VLESS")) o:value("vless", translate("VLESS"))
o:value("http", translate("HTTP")) o:value("http", translate("HTTP"))
@ -45,9 +45,9 @@ o:value("_balancing", translate("Balancing"))
o:value("_shunt", translate("Shunt")) o:value("_shunt", translate("Shunt"))
o:value("_iface", translate("Custom Interface")) o:value("_iface", translate("Custom Interface"))
o = s:option(Value, option_name("iface"), translate("Interface")) o = s:option(Value, _n("iface"), translate("Interface"))
o.default = "eth1" o.default = "eth1"
o:depends({ [option_name("protocol")] = "_iface" }) o:depends({ [_n("protocol")] = "_iface" })
local nodes_table = {} local nodes_table = {}
local balancers_table = {} local balancers_table = {}
@ -96,12 +96,12 @@ uci:foreach(appname, "socks", function(s)
end) end)
-- 负载均衡列表 -- 负载均衡列表
local o = s:option(DynamicList, option_name("balancing_node"), translate("Load balancing node list"), translate("Load balancing node list, <a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>document</a>")) local o = s:option(DynamicList, _n("balancing_node"), translate("Load balancing node list"), translate("Load balancing node list, <a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>document</a>"))
o:depends({ [option_name("protocol")] = "_balancing" }) o:depends({ [_n("protocol")] = "_balancing" })
for k, v in pairs(nodes_table) do o:value(v.id, v.remark) end for k, v in pairs(nodes_table) do o:value(v.id, v.remark) end
local o = s:option(ListValue, option_name("balancingStrategy"), translate("Balancing Strategy")) local o = s:option(ListValue, _n("balancingStrategy"), translate("Balancing Strategy"))
o:depends({ [option_name("protocol")] = "_balancing" }) o:depends({ [_n("protocol")] = "_balancing" })
o:value("random") o:value("random")
o:value("roundRobin") o:value("roundRobin")
o:value("leastPing") o:value("leastPing")
@ -109,11 +109,11 @@ o.default = "leastPing"
-- Fallback Node -- Fallback Node
if api.compare_versions(xray_version, ">=", "1.8.10") then if api.compare_versions(xray_version, ">=", "1.8.10") then
local o = s:option(ListValue, option_name("fallback_node"), translate("Fallback Node")) local o = s:option(ListValue, _n("fallback_node"), translate("Fallback Node"))
if api.compare_versions(xray_version, ">=", "1.8.12") then if api.compare_versions(xray_version, ">=", "1.8.12") then
o:depends({ [option_name("protocol")] = "_balancing" }) o:depends({ [_n("protocol")] = "_balancing" })
else else
o:depends({ [option_name("balancingStrategy")] = "leastPing" }) o:depends({ [_n("balancingStrategy")] = "leastPing" })
end end
local function check_fallback_chain(fb) local function check_fallback_chain(fb)
for k, v in pairs(fallback_table) do for k, v in pairs(fallback_table) do
@ -132,11 +132,11 @@ if api.compare_versions(xray_version, ">=", "1.8.10") then
end end
-- 探测地址 -- 探测地址
local ucpu = s:option(Flag, option_name("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL.")) local ucpu = s:option(Flag, _n("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
ucpu:depends({ [option_name("balancingStrategy")] = "leastPing" }) ucpu:depends({ [_n("balancingStrategy")] = "leastPing" })
local pu = s:option(Value, option_name("probeUrl"), translate("Probe URL")) local pu = s:option(Value, _n("probeUrl"), translate("Probe URL"))
pu:depends({ [option_name("useCustomProbeUrl")] = true }) pu:depends({ [_n("useCustomProbeUrl")] = true })
pu:value("https://cp.cloudflare.com/", "Cloudflare") pu:value("https://cp.cloudflare.com/", "Cloudflare")
pu:value("https://www.gstatic.com/generate_204", "Gstatic") pu:value("https://www.gstatic.com/generate_204", "Gstatic")
pu:value("https://www.google.com/generate_204", "Google") pu:value("https://www.google.com/generate_204", "Google")
@ -147,27 +147,27 @@ pu.default = "https://www.google.com/generate_204"
pu.description = translate("The URL used to detect the connection status.") pu.description = translate("The URL used to detect the connection status.")
-- 探测间隔 -- 探测间隔
local pi = s:option(Value, option_name("probeInterval"), translate("Probe Interval")) local pi = s:option(Value, _n("probeInterval"), translate("Probe Interval"))
pi:depends({ [option_name("balancingStrategy")] = "leastPing" }) pi:depends({ [_n("balancingStrategy")] = "leastPing" })
pi.default = "1m" pi.default = "1m"
pi.description = translate("The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.") pi.description = translate("The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.")
if api.compare_versions(xray_version, ">=", "1.8.12") then if api.compare_versions(xray_version, ">=", "1.8.12") then
ucpu:depends({ [option_name("protocol")] = "_balancing" }) ucpu:depends({ [_n("protocol")] = "_balancing" })
pi:depends({ [option_name("protocol")] = "_balancing" }) pi:depends({ [_n("protocol")] = "_balancing" })
else else
ucpu:depends({ [option_name("balancingStrategy")] = "leastPing" }) ucpu:depends({ [_n("balancingStrategy")] = "leastPing" })
pi:depends({ [option_name("balancingStrategy")] = "leastPing" }) pi:depends({ [_n("balancingStrategy")] = "leastPing" })
end end
-- [[ 分流模块 ]] -- [[ 分流模块 ]]
if #nodes_table > 0 then if #nodes_table > 0 then
o = s:option(Flag, option_name("preproxy_enabled"), translate("Preproxy")) o = s:option(Flag, _n("preproxy_enabled"), translate("Preproxy"))
o:depends({ [option_name("protocol")] = "_shunt" }) o:depends({ [_n("protocol")] = "_shunt" })
o = s:option(ListValue, option_name("main_node"), string.format('<a style="color:red">%s</a>', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including <code>Default</code>) has a separate switch that controls whether this rule uses the pre-proxy or not.")) o = s:option(ListValue, _n("main_node"), string.format('<a style="color:red">%s</a>', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including <code>Default</code>) has a separate switch that controls whether this rule uses the pre-proxy or not."))
o:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true }) o:depends({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true })
for k, v in pairs(socks_list) do for k, v in pairs(socks_list) do
o:value(v.id, v.remark) o:value(v.id, v.remark)
end end
@ -180,16 +180,15 @@ if #nodes_table > 0 then
for k, v in pairs(nodes_table) do for k, v in pairs(nodes_table) do
o:value(v.id, v.remark) o:value(v.id, v.remark)
end end
o.default = "nil"
end end
uci:foreach(appname, "shunt_rules", function(e) uci:foreach(appname, "shunt_rules", function(e)
if e[".name"] and e.remarks then if e[".name"] and e.remarks then
o = s:option(ListValue, option_name(e[".name"]), string.format('* <a href="%s" target="_blank">%s</a>', api.url("shunt_rules", e[".name"]), e.remarks)) o = s:option(ListValue, _n(e[".name"]), string.format('* <a href="%s" target="_blank">%s</a>', api.url("shunt_rules", e[".name"]), e.remarks))
o:value("nil", translate("Close")) o:value("", translate("Close"))
o:value("_default", translate("Default")) o:value("_default", translate("Default"))
o:value("_direct", translate("Direct Connection")) o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole")) o:value("_blackhole", translate("Blackhole"))
o:depends({ [option_name("protocol")] = "_shunt" }) o:depends({ [_n("protocol")] = "_shunt" })
if #nodes_table > 0 then if #nodes_table > 0 then
for k, v in pairs(socks_list) do for k, v in pairs(socks_list) do
@ -201,28 +200,27 @@ uci:foreach(appname, "shunt_rules", function(e)
for k, v in pairs(iface_table) do for k, v in pairs(iface_table) do
o:value(v.id, v.remark) o:value(v.id, v.remark)
end end
local pt = s:option(ListValue, option_name(e[".name"] .. "_proxy_tag"), string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy"))) local pt = s:option(ListValue, _n(e[".name"] .. "_proxy_tag"), string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy")))
pt:value("nil", translate("Close")) pt:value("", translate("Close"))
pt:value("main", translate("Preproxy Node")) pt:value("main", translate("Preproxy Node"))
pt.default = "nil"
for k, v in pairs(nodes_table) do for k, v in pairs(nodes_table) do
o:value(v.id, v.remark) o:value(v.id, v.remark)
pt:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true, [option_name(e[".name"])] = v.id }) pt:depends({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true, [_n(e[".name"])] = v.id })
end end
end end
end end
end) end)
o = s:option(DummyValue, option_name("shunt_tips"), " ") o = s:option(DummyValue, _n("shunt_tips"), " ")
o.not_rewrite = true o.not_rewrite = true
o.rawhtml = true o.rawhtml = true
o.cfgvalue = function(t, n) o.cfgvalue = function(t, n)
return string.format('<a style="color: red" href="../rule">%s</a>', translate("No shunt rules? Click me to go to add.")) return string.format('<a style="color: red" href="../rule">%s</a>', translate("No shunt rules? Click me to go to add."))
end end
o:depends({ [option_name("protocol")] = "_shunt" }) o:depends({ [_n("protocol")] = "_shunt" })
local o = s:option(ListValue, option_name("default_node"), string.format('* <a style="color:red">%s</a>', translate("Default"))) local o = s:option(ListValue, _n("default_node"), string.format('* <a style="color:red">%s</a>', translate("Default")))
o:depends({ [option_name("protocol")] = "_shunt" }) o:depends({ [_n("protocol")] = "_shunt" })
o:value("_direct", translate("Direct Connection")) o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole")) o:value("_blackhole", translate("Blackhole"))
@ -236,17 +234,16 @@ if #nodes_table > 0 then
for k, v in pairs(iface_table) do for k, v in pairs(iface_table) do
o:value(v.id, v.remark) o:value(v.id, v.remark)
end end
local dpt = s:option(ListValue, option_name("default_proxy_tag"), string.format('* <a style="color:red">%s</a>', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node.")) local dpt = s:option(ListValue, _n("default_proxy_tag"), string.format('* <a style="color:red">%s</a>', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node."))
dpt:value("nil", translate("Close")) dpt:value("", translate("Close"))
dpt:value("main", translate("Preproxy Node")) dpt:value("main", translate("Preproxy Node"))
dpt.default = "nil"
for k, v in pairs(nodes_table) do for k, v in pairs(nodes_table) do
o:value(v.id, v.remark) o:value(v.id, v.remark)
dpt:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true, [option_name("default_node")] = v.id }) dpt:depends({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true, [_n("default_node")] = v.id })
end end
end end
o = s:option(ListValue, option_name("domainStrategy"), translate("Domain Strategy")) o = s:option(ListValue, _n("domainStrategy"), translate("Domain Strategy"))
o:value("AsIs") o:value("AsIs")
o:value("IPIfNonMatch") o:value("IPIfNonMatch")
o:value("IPOnDemand") o:value("IPOnDemand")
@ -255,92 +252,92 @@ o.description = "<br /><ul><li>" .. translate("'AsIs': Only use domain for routi
.. "</li><li>" .. translate("'IPIfNonMatch': When no rule matches current domain, resolves it into IP addresses (A or AAAA records) and try all rules again.") .. "</li><li>" .. translate("'IPIfNonMatch': When no rule matches current domain, resolves it into IP addresses (A or AAAA records) and try all rules again.")
.. "</li><li>" .. translate("'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately.") .. "</li><li>" .. translate("'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately.")
.. "</li></ul>" .. "</li></ul>"
o:depends({ [option_name("protocol")] = "_shunt" }) o:depends({ [_n("protocol")] = "_shunt" })
o = s:option(ListValue, option_name("domainMatcher"), translate("Domain matcher")) o = s:option(ListValue, _n("domainMatcher"), translate("Domain matcher"))
o:value("hybrid") o:value("hybrid")
o:value("linear") o:value("linear")
o:depends({ [option_name("protocol")] = "_shunt" }) o:depends({ [_n("protocol")] = "_shunt" })
-- [[ 分流模块 End ]] -- [[ 分流模块 End ]]
o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
o = s:option(Value, option_name("port"), translate("Port")) o = s:option(Value, _n("port"), translate("Port"))
o.datatype = "port" o.datatype = "port"
local protocols = s.fields[option_name("protocol")].keylist local protocols = s.fields[_n("protocol")].keylist
if #protocols > 0 then if #protocols > 0 then
for index, value in ipairs(protocols) do for index, value in ipairs(protocols) do
if not value:find("_") then if not value:find("_") then
s.fields[option_name("address")]:depends({ [option_name("protocol")] = value }) s.fields[_n("address")]:depends({ [_n("protocol")] = value })
s.fields[option_name("port")]:depends({ [option_name("protocol")] = value }) s.fields[_n("port")]:depends({ [_n("protocol")] = value })
end end
end end
end end
o = s:option(Value, option_name("username"), translate("Username")) o = s:option(Value, _n("username"), translate("Username"))
o:depends({ [option_name("protocol")] = "http" }) o:depends({ [_n("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o = s:option(Value, option_name("password"), translate("Password")) o = s:option(Value, _n("password"), translate("Password"))
o.password = true o.password = true
o:depends({ [option_name("protocol")] = "http" }) o:depends({ [_n("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
o = s:option(ListValue, option_name("security"), translate("Encrypt Method")) o = s:option(ListValue, _n("security"), translate("Encrypt Method"))
for a, t in ipairs(security_list) do o:value(t) end for a, t in ipairs(security_list) do o:value(t) end
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o = s:option(Value, option_name("encryption"), translate("Encrypt Method")) o = s:option(Value, _n("encryption"), translate("Encrypt Method"))
o.default = "none" o.default = "none"
o:value("none") o:value("none")
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o = s:option(ListValue, option_name("ss_method"), translate("Encrypt Method")) o = s:option(ListValue, _n("ss_method"), translate("Encrypt Method"))
o.rewrite_option = "method" o.rewrite_option = "method"
for a, t in ipairs(ss_method_list) do o:value(t) end for a, t in ipairs(ss_method_list) do o:value(t) end
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(Flag, option_name("iv_check"), translate("IV Check")) o = s:option(Flag, _n("iv_check"), translate("IV Check"))
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "aes-128-gcm" }) o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "aes-128-gcm" })
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "aes-256-gcm" }) o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "aes-256-gcm" })
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "chacha20-poly1305" }) o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "chacha20-poly1305" })
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "xchacha20-poly1305" }) o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "xchacha20-poly1305" })
o = s:option(Flag, option_name("uot"), translate("UDP over TCP")) o = s:option(Flag, _n("uot"), translate("UDP over TCP"))
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(Value, option_name("uuid"), translate("ID")) o = s:option(Value, _n("uuid"), translate("ID"))
o.password = true o.password = true
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o = s:option(ListValue, option_name("flow"), translate("flow")) o = s:option(ListValue, _n("flow"), translate("flow"))
o.default = "" o.default = ""
o:value("", translate("Disable")) o:value("", translate("Disable"))
o:value("xtls-rprx-vision") o:value("xtls-rprx-vision")
o:depends({ [option_name("protocol")] = "vless", [option_name("tls")] = true, [option_name("transport")] = "raw" }) o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true, [_n("transport")] = "raw" })
o = s:option(Flag, option_name("tls"), translate("TLS")) o = s:option(Flag, _n("tls"), translate("TLS"))
o.default = 0 o.default = 0
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "http" }) o:depends({ [_n("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(Flag, option_name("reality"), translate("REALITY"), translate("Only recommend to use with VLESS-TCP-XTLS-Vision.")) o = s:option(Flag, _n("reality"), translate("REALITY"), translate("Only recommend to use with VLESS-TCP-XTLS-Vision."))
o.default = 0 o.default = 0
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "raw" }) o:depends({ [_n("tls")] = true, [_n("transport")] = "raw" })
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "h2" }) o:depends({ [_n("tls")] = true, [_n("transport")] = "h2" })
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "grpc" }) o:depends({ [_n("tls")] = true, [_n("transport")] = "grpc" })
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "xhttp" }) o:depends({ [_n("tls")] = true, [_n("transport")] = "xhttp" })
o = s:option(ListValue, option_name("alpn"), translate("alpn")) o = s:option(ListValue, _n("alpn"), translate("alpn"))
o.default = "default" o.default = "default"
o:value("default", translate("Default")) o:value("default", translate("Default"))
o:value("h3") o:value("h3")
@ -349,36 +346,36 @@ o:value("h3,h2")
o:value("http/1.1") o:value("http/1.1")
o:value("h2,http/1.1") o:value("h2,http/1.1")
o:value("h3,h2,http/1.1") o:value("h3,h2,http/1.1")
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false }) o:depends({ [_n("tls")] = true, [_n("reality")] = false })
-- o = s:option(Value, option_name("minversion"), translate("minversion")) -- o = s:option(Value, _n("minversion"), translate("minversion"))
-- o.default = "1.3" -- o.default = "1.3"
-- o:value("1.3") -- o:value("1.3")
-- o:depends({ [option_name("tls")] = true }) -- o:depends({ [_n("tls")] = true })
o = s:option(Value, option_name("tls_serverName"), translate("Domain")) o = s:option(Value, _n("tls_serverName"), translate("Domain"))
o:depends({ [option_name("tls")] = true }) o:depends({ [_n("tls")] = true })
o = s:option(Flag, option_name("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped."))
o.default = "0" o.default = "0"
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false }) o:depends({ [_n("tls")] = true, [_n("reality")] = false })
-- [[ REALITY部分 ]] -- -- [[ REALITY部分 ]] --
o = s:option(Value, option_name("reality_publicKey"), translate("Public Key")) o = s:option(Value, _n("reality_publicKey"), translate("Public Key"))
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true }) o:depends({ [_n("tls")] = true, [_n("reality")] = true })
o = s:option(Value, option_name("reality_shortId"), translate("Short Id")) o = s:option(Value, _n("reality_shortId"), translate("Short Id"))
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true }) o:depends({ [_n("tls")] = true, [_n("reality")] = true })
o = s:option(Value, option_name("reality_spiderX"), translate("Spider X")) o = s:option(Value, _n("reality_spiderX"), translate("Spider X"))
o.placeholder = "/" o.placeholder = "/"
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true }) o:depends({ [_n("tls")] = true, [_n("reality")] = true })
o = s:option(Flag, option_name("utls"), translate("uTLS")) o = s:option(Flag, _n("utls"), translate("uTLS"))
o.default = "0" o.default = "0"
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false }) o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o = s:option(ListValue, option_name("fingerprint"), translate("Finger Print")) o = s:option(ListValue, _n("fingerprint"), translate("Finger Print"))
o:value("chrome") o:value("chrome")
o:value("firefox") o:value("firefox")
o:value("edge") o:value("edge")
@ -390,10 +387,10 @@ o:value("android")
o:value("random") o:value("random")
o:value("randomized") o:value("randomized")
o.default = "chrome" o.default = "chrome"
o:depends({ [option_name("tls")] = true, [option_name("utls")] = true }) o:depends({ [_n("tls")] = true, [_n("utls")] = true })
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true }) o:depends({ [_n("tls")] = true, [_n("reality")] = true })
o = s:option(ListValue, option_name("transport"), translate("Transport")) o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("raw", "RAW (TCP)") o:value("raw", "RAW (TCP)")
o:value("mkcp", "mKCP") o:value("mkcp", "mKCP")
o:value("ws", "WebSocket") o:value("ws", "WebSocket")
@ -403,193 +400,193 @@ o:value("quic", "QUIC")
o:value("grpc", "gRPC") o:value("grpc", "gRPC")
o:value("httpupgrade", "HttpUpgrade") o:value("httpupgrade", "HttpUpgrade")
o:value("xhttp", "XHTTP (SplitHTTP)") o:value("xhttp", "XHTTP (SplitHTTP)")
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
o = s:option(Value, option_name("wireguard_public_key"), translate("Public Key")) o = s:option(Value, _n("wireguard_public_key"), translate("Public Key"))
o:depends({ [option_name("protocol")] = "wireguard" }) o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(Value, option_name("wireguard_secret_key"), translate("Private Key")) o = s:option(Value, _n("wireguard_secret_key"), translate("Private Key"))
o:depends({ [option_name("protocol")] = "wireguard" }) o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(Value, option_name("wireguard_preSharedKey"), translate("Pre shared key")) o = s:option(Value, _n("wireguard_preSharedKey"), translate("Pre shared key"))
o:depends({ [option_name("protocol")] = "wireguard" }) o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(DynamicList, option_name("wireguard_local_address"), translate("Local Address")) o = s:option(DynamicList, _n("wireguard_local_address"), translate("Local Address"))
o:depends({ [option_name("protocol")] = "wireguard" }) o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(Value, option_name("wireguard_mtu"), translate("MTU")) o = s:option(Value, _n("wireguard_mtu"), translate("MTU"))
o.default = "1420" o.default = "1420"
o:depends({ [option_name("protocol")] = "wireguard" }) o:depends({ [_n("protocol")] = "wireguard" })
if api.compare_versions(xray_version, ">=", "1.8.0") then if api.compare_versions(xray_version, ">=", "1.8.0") then
o = s:option(Value, option_name("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings.")) o = s:option(Value, _n("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings."))
o:depends({ [option_name("protocol")] = "wireguard" }) o:depends({ [_n("protocol")] = "wireguard" })
end end
o = s:option(Value, option_name("wireguard_keepAlive"), translate("Keep Alive")) o = s:option(Value, _n("wireguard_keepAlive"), translate("Keep Alive"))
o.default = "0" o.default = "0"
o:depends({ [option_name("protocol")] = "wireguard" }) o:depends({ [_n("protocol")] = "wireguard" })
-- [[ RAW部分 ]]-- -- [[ RAW部分 ]]--
-- TCP伪装 -- TCP伪装
o = s:option(ListValue, option_name("tcp_guise"), translate("Camouflage Type")) o = s:option(ListValue, _n("tcp_guise"), translate("Camouflage Type"))
o:value("none", "none") o:value("none", "none")
o:value("http", "http") o:value("http", "http")
o:depends({ [option_name("transport")] = "raw" }) o:depends({ [_n("transport")] = "raw" })
-- HTTP域名 -- HTTP域名
o = s:option(DynamicList, option_name("tcp_guise_http_host"), translate("HTTP Host")) o = s:option(DynamicList, _n("tcp_guise_http_host"), translate("HTTP Host"))
o:depends({ [option_name("tcp_guise")] = "http" }) o:depends({ [_n("tcp_guise")] = "http" })
-- HTTP路径 -- HTTP路径
o = s:option(DynamicList, option_name("tcp_guise_http_path"), translate("HTTP Path")) o = s:option(DynamicList, _n("tcp_guise_http_path"), translate("HTTP Path"))
o.placeholder = "/" o.placeholder = "/"
o:depends({ [option_name("tcp_guise")] = "http" }) o:depends({ [_n("tcp_guise")] = "http" })
-- [[ mKCP部分 ]]-- -- [[ mKCP部分 ]]--
o = s:option(ListValue, option_name("mkcp_guise"), translate("Camouflage Type"), translate('<br />none: default, no masquerade, data sent is packets with no characteristics.<br />srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).<br />utp: packets disguised as uTP will be recognized as bittorrent downloaded data.<br />wechat-video: packets disguised as WeChat video calls.<br />dtls: disguised as DTLS 1.2 packet.<br />wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)')) o = s:option(ListValue, _n("mkcp_guise"), translate("Camouflage Type"), translate('<br />none: default, no masquerade, data sent is packets with no characteristics.<br />srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).<br />utp: packets disguised as uTP will be recognized as bittorrent downloaded data.<br />wechat-video: packets disguised as WeChat video calls.<br />dtls: disguised as DTLS 1.2 packet.<br />wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)'))
for a, t in ipairs(header_type_list) do o:value(t) end for a, t in ipairs(header_type_list) do o:value(t) end
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_mtu"), translate("KCP MTU")) o = s:option(Value, _n("mkcp_mtu"), translate("KCP MTU"))
o.default = "1350" o.default = "1350"
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_tti"), translate("KCP TTI")) o = s:option(Value, _n("mkcp_tti"), translate("KCP TTI"))
o.default = "20" o.default = "20"
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_uplinkCapacity"), translate("KCP uplinkCapacity")) o = s:option(Value, _n("mkcp_uplinkCapacity"), translate("KCP uplinkCapacity"))
o.default = "5" o.default = "5"
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_downlinkCapacity"), translate("KCP downlinkCapacity")) o = s:option(Value, _n("mkcp_downlinkCapacity"), translate("KCP downlinkCapacity"))
o.default = "20" o.default = "20"
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Flag, option_name("mkcp_congestion"), translate("KCP Congestion")) o = s:option(Flag, _n("mkcp_congestion"), translate("KCP Congestion"))
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_readBufferSize"), translate("KCP readBufferSize")) o = s:option(Value, _n("mkcp_readBufferSize"), translate("KCP readBufferSize"))
o.default = "1" o.default = "1"
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_writeBufferSize"), translate("KCP writeBufferSize")) o = s:option(Value, _n("mkcp_writeBufferSize"), translate("KCP writeBufferSize"))
o.default = "1" o.default = "1"
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_seed"), translate("KCP Seed")) o = s:option(Value, _n("mkcp_seed"), translate("KCP Seed"))
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
-- [[ WebSocket部分 ]]-- -- [[ WebSocket部分 ]]--
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host")) o = s:option(Value, _n("ws_host"), translate("WebSocket Host"))
o:depends({ [option_name("transport")] = "ws" }) o:depends({ [_n("transport")] = "ws" })
o = s:option(Value, option_name("ws_path"), translate("WebSocket Path")) o = s:option(Value, _n("ws_path"), translate("WebSocket Path"))
o.placeholder = "/" o.placeholder = "/"
o:depends({ [option_name("transport")] = "ws" }) o:depends({ [_n("transport")] = "ws" })
o = s:option(Value, option_name("ws_heartbeatPeriod"), translate("HeartbeatPeriod(second)")) o = s:option(Value, _n("ws_heartbeatPeriod"), translate("HeartbeatPeriod(second)"))
o.datatype = "integer" o.datatype = "integer"
o:depends({ [option_name("transport")] = "ws" }) o:depends({ [_n("transport")] = "ws" })
-- [[ HTTP/2部分 ]]-- -- [[ HTTP/2部分 ]]--
o = s:option(Value, option_name("h2_host"), translate("HTTP/2 Host")) o = s:option(Value, _n("h2_host"), translate("HTTP/2 Host"))
o:depends({ [option_name("transport")] = "h2" }) o:depends({ [_n("transport")] = "h2" })
o = s:option(Value, option_name("h2_path"), translate("HTTP/2 Path")) o = s:option(Value, _n("h2_path"), translate("HTTP/2 Path"))
o.placeholder = "/" o.placeholder = "/"
o:depends({ [option_name("transport")] = "h2" }) o:depends({ [_n("transport")] = "h2" })
o = s:option(Flag, option_name("h2_health_check"), translate("Health check")) o = s:option(Flag, _n("h2_health_check"), translate("Health check"))
o:depends({ [option_name("transport")] = "h2" }) o:depends({ [_n("transport")] = "h2" })
o = s:option(Value, option_name("h2_read_idle_timeout"), translate("Idle timeout")) o = s:option(Value, _n("h2_read_idle_timeout"), translate("Idle timeout"))
o.default = "10" o.default = "10"
o:depends({ [option_name("h2_health_check")] = true }) o:depends({ [_n("h2_health_check")] = true })
o = s:option(Value, option_name("h2_health_check_timeout"), translate("Health check timeout")) o = s:option(Value, _n("h2_health_check_timeout"), translate("Health check timeout"))
o.default = "15" o.default = "15"
o:depends({ [option_name("h2_health_check")] = true }) o:depends({ [_n("h2_health_check")] = true })
-- [[ DomainSocket部分 ]]-- -- [[ DomainSocket部分 ]]--
o = s:option(Value, option_name("ds_path"), "Path", translate("A legal file path. This file must not exist before running.")) o = s:option(Value, _n("ds_path"), "Path", translate("A legal file path. This file must not exist before running."))
o:depends({ [option_name("transport")] = "ds" }) o:depends({ [_n("transport")] = "ds" })
-- [[ QUIC部分 ]]-- -- [[ QUIC部分 ]]--
o = s:option(ListValue, option_name("quic_security"), translate("Encrypt Method")) o = s:option(ListValue, _n("quic_security"), translate("Encrypt Method"))
o:value("none") o:value("none")
o:value("aes-128-gcm") o:value("aes-128-gcm")
o:value("chacha20-poly1305") o:value("chacha20-poly1305")
o:depends({ [option_name("transport")] = "quic" }) o:depends({ [_n("transport")] = "quic" })
o = s:option(Value, option_name("quic_key"), translate("Encrypt Method") .. translate("Key")) o = s:option(Value, _n("quic_key"), translate("Encrypt Method") .. translate("Key"))
o:depends({ [option_name("transport")] = "quic" }) o:depends({ [_n("transport")] = "quic" })
o = s:option(ListValue, option_name("quic_guise"), translate("Camouflage Type")) o = s:option(ListValue, _n("quic_guise"), translate("Camouflage Type"))
for a, t in ipairs(header_type_list) do o:value(t) end for a, t in ipairs(header_type_list) do o:value(t) end
o:depends({ [option_name("transport")] = "quic" }) o:depends({ [_n("transport")] = "quic" })
-- [[ gRPC部分 ]]-- -- [[ gRPC部分 ]]--
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName") o = s:option(Value, _n("grpc_serviceName"), "ServiceName")
o:depends({ [option_name("transport")] = "grpc" }) o:depends({ [_n("transport")] = "grpc" })
o = s:option(ListValue, option_name("grpc_mode"), "gRPC " .. translate("Transfer mode")) o = s:option(ListValue, _n("grpc_mode"), "gRPC " .. translate("Transfer mode"))
o:value("gun") o:value("gun")
o:value("multi") o:value("multi")
o:depends({ [option_name("transport")] = "grpc" }) o:depends({ [_n("transport")] = "grpc" })
o = s:option(Flag, option_name("grpc_health_check"), translate("Health check")) o = s:option(Flag, _n("grpc_health_check"), translate("Health check"))
o:depends({ [option_name("transport")] = "grpc" }) o:depends({ [_n("transport")] = "grpc" })
o = s:option(Value, option_name("grpc_idle_timeout"), translate("Idle timeout")) o = s:option(Value, _n("grpc_idle_timeout"), translate("Idle timeout"))
o.default = "10" o.default = "10"
o:depends({ [option_name("grpc_health_check")] = true }) o:depends({ [_n("grpc_health_check")] = true })
o = s:option(Value, option_name("grpc_health_check_timeout"), translate("Health check timeout")) o = s:option(Value, _n("grpc_health_check_timeout"), translate("Health check timeout"))
o.default = "20" o.default = "20"
o:depends({ [option_name("grpc_health_check")] = true }) o:depends({ [_n("grpc_health_check")] = true })
o = s:option(Flag, option_name("grpc_permit_without_stream"), translate("Permit without stream")) o = s:option(Flag, _n("grpc_permit_without_stream"), translate("Permit without stream"))
o.default = "0" o.default = "0"
o:depends({ [option_name("grpc_health_check")] = true }) o:depends({ [_n("grpc_health_check")] = true })
o = s:option(Value, option_name("grpc_initial_windows_size"), translate("Initial Windows Size")) o = s:option(Value, _n("grpc_initial_windows_size"), translate("Initial Windows Size"))
o.default = "0" o.default = "0"
o:depends({ [option_name("transport")] = "grpc" }) o:depends({ [_n("transport")] = "grpc" })
-- [[ HttpUpgrade部分 ]]-- -- [[ HttpUpgrade部分 ]]--
o = s:option(Value, option_name("httpupgrade_host"), translate("HttpUpgrade Host")) o = s:option(Value, _n("httpupgrade_host"), translate("HttpUpgrade Host"))
o:depends({ [option_name("transport")] = "httpupgrade" }) o:depends({ [_n("transport")] = "httpupgrade" })
o = s:option(Value, option_name("httpupgrade_path"), translate("HttpUpgrade Path")) o = s:option(Value, _n("httpupgrade_path"), translate("HttpUpgrade Path"))
o.placeholder = "/" o.placeholder = "/"
o:depends({ [option_name("transport")] = "httpupgrade" }) o:depends({ [_n("transport")] = "httpupgrade" })
-- [[ XHTTP部分 ]]-- -- [[ XHTTP部分 ]]--
o = s:option(ListValue, option_name("xhttp_mode"), "XHTTP " .. translate("Mode")) o = s:option(ListValue, _n("xhttp_mode"), "XHTTP " .. translate("Mode"))
o:depends({ [option_name("transport")] = "xhttp" }) o:depends({ [_n("transport")] = "xhttp" })
o.default = "auto" o.default = "auto"
o:value("auto") o:value("auto")
o:value("packet-up") o:value("packet-up")
o:value("stream-up") o:value("stream-up")
o:value("stream-one") o:value("stream-one")
o = s:option(Value, option_name("xhttp_host"), translate("XHTTP Host")) o = s:option(Value, _n("xhttp_host"), translate("XHTTP Host"))
o:depends({ [option_name("transport")] = "xhttp" }) o:depends({ [_n("transport")] = "xhttp" })
o = s:option(Value, option_name("xhttp_path"), translate("XHTTP Path")) o = s:option(Value, _n("xhttp_path"), translate("XHTTP Path"))
o.placeholder = "/" o.placeholder = "/"
o:depends({ [option_name("transport")] = "xhttp" }) o:depends({ [_n("transport")] = "xhttp" })
o = s:option(TextValue, option_name("xhttp_extra"), translate("XHTTP Extra"), translate("An <a target='_blank' href='https://xtls.github.io/config/transports/splithttp.html#extra'>XHTTP extra object</a> in raw json")) o = s:option(TextValue, _n("xhttp_extra"), translate("XHTTP Extra"), translate("An <a target='_blank' href='https://xtls.github.io/config/transports/splithttp.html#extra'>XHTTP extra object</a> in raw json"))
o:depends({ [option_name("transport")] = "xhttp" }) o:depends({ [_n("transport")] = "xhttp" })
o.rows = 15 o.rows = 15
o.wrap = "off" o.wrap = "off"
o.custom_write = function(self, section, value) o.custom_write = function(self, section, value)
@ -618,62 +615,62 @@ o.validate = function(self, value)
end end
-- [[ Mux.Cool ]]-- -- [[ Mux.Cool ]]--
o = s:option(Flag, option_name("mux"), "Mux", translate("Enable Mux.Cool")) o = s:option(Flag, _n("mux"), "Mux", translate("Enable Mux.Cool"))
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless", [option_name("flow")] = "" }) o:depends({ [_n("protocol")] = "vless", [_n("flow")] = "" })
o:depends({ [option_name("protocol")] = "http" }) o:depends({ [_n("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
o = s:option(Value, option_name("mux_concurrency"), translate("Mux concurrency")) o = s:option(Value, _n("mux_concurrency"), translate("Mux concurrency"))
o.default = 8 o.default = 8
o:depends({ [option_name("mux")] = true }) o:depends({ [_n("mux")] = true })
-- [[ XUDP Mux ]]-- -- [[ XUDP Mux ]]--
o = s:option(Flag, option_name("xmux"), "XUDP Mux") o = s:option(Flag, _n("xmux"), "XUDP Mux")
o.default = 1 o.default = 1
o:depends({ [option_name("protocol")] = "vless", [option_name("flow")] = "xtls-rprx-vision" }) o:depends({ [_n("protocol")] = "vless", [_n("flow")] = "xtls-rprx-vision" })
o = s:option(Value, option_name("xudp_concurrency"), translate("XUDP Mux concurrency")) o = s:option(Value, _n("xudp_concurrency"), translate("XUDP Mux concurrency"))
o.default = 8 o.default = 8
o:depends({ [option_name("xmux")] = true }) o:depends({ [_n("xmux")] = true })
--[[tcpMptcp]] --[[tcpMptcp]]
o = s:option(Flag, option_name("tcpMptcp"), "tcpMptcp", translate("Enable Multipath TCP, need to be enabled in both server and client configuration.")) o = s:option(Flag, _n("tcpMptcp"), "tcpMptcp", translate("Enable Multipath TCP, need to be enabled in both server and client configuration."))
o.default = 0 o.default = 0
o = s:option(Flag, option_name("tcpNoDelay"), "tcpNoDelay") o = s:option(Flag, _n("tcpNoDelay"), "tcpNoDelay")
o.default = 0 o.default = 0
o = s:option(ListValue, option_name("chain_proxy"), translate("Chain Proxy")) o = s:option(ListValue, _n("chain_proxy"), translate("Chain Proxy"))
o:value("", translate("Close(Not use)")) o:value("", translate("Close(Not use)"))
o:value("1", translate("Preproxy Node")) o:value("1", translate("Preproxy Node"))
o:value("2", translate("Landing Node")) o:value("2", translate("Landing Node"))
for i, v in ipairs(s.fields[option_name("protocol")].keylist) do for i, v in ipairs(s.fields[_n("protocol")].keylist) do
if not v:find("_") then if not v:find("_") then
o:depends({ [option_name("protocol")] = v }) o:depends({ [_n("protocol")] = v })
end end
end end
o = s:option(ListValue, option_name("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy.")) o = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
o:depends({ [option_name("chain_proxy")] = "1" }) o:depends({ [_n("chain_proxy")] = "1" })
o = s:option(ListValue, option_name("to_node"), translate("Landing Node"), translate("Only support a layer of proxy.")) o = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
o:depends({ [option_name("chain_proxy")] = "2" }) o:depends({ [_n("chain_proxy")] = "2" })
for k, v in pairs(nodes_table) do for k, v in pairs(nodes_table) do
if v.type == "Xray" and v.id ~= arg[1] then if v.type == "Xray" and v.id ~= arg[1] then
s.fields[option_name("preproxy_node")]:value(v.id, v.remark) s.fields[_n("preproxy_node")]:value(v.id, v.remark)
s.fields[option_name("to_node")]:value(v.id, v.remark) s.fields[_n("to_node")]:value(v.id, v.remark)
end end
end end
for i, v in ipairs(s.fields[option_name("protocol")].keylist) do for i, v in ipairs(s.fields[_n("protocol")].keylist) do
if not v:find("_") then if not v:find("_") then
s.fields[option_name("tcpMptcp")]:depends({ [option_name("protocol")] = v }) s.fields[_n("tcpMptcp")]:depends({ [_n("protocol")] = v })
s.fields[option_name("tcpNoDelay")]:depends({ [option_name("protocol")] = v }) s.fields[_n("tcpNoDelay")]:depends({ [_n("protocol")] = v })
s.fields[option_name("chain_proxy")]:depends({ [option_name("protocol")] = v }) s.fields[_n("chain_proxy")]:depends({ [_n("protocol")] = v })
end end
end end

View File

@ -17,7 +17,7 @@ local type_name = "sing-box"
local option_prefix = "singbox_" local option_prefix = "singbox_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -35,7 +35,7 @@ local security_list = { "none", "auto", "aes-128-gcm", "chacha20-poly1305", "zer
s.fields["type"]:value(type_name, "Sing-Box") s.fields["type"]:value(type_name, "Sing-Box")
o = s:option(ListValue, option_name("protocol"), translate("Protocol")) o = s:option(ListValue, _n("protocol"), translate("Protocol"))
o:value("socks", "Socks") o:value("socks", "Socks")
o:value("http", "HTTP") o:value("http", "HTTP")
o:value("shadowsocks", "Shadowsocks") o:value("shadowsocks", "Shadowsocks")
@ -60,9 +60,9 @@ end
o:value("_shunt", translate("Shunt")) o:value("_shunt", translate("Shunt"))
o:value("_iface", translate("Custom Interface")) o:value("_iface", translate("Custom Interface"))
o = s:option(Value, option_name("iface"), translate("Interface")) o = s:option(Value, _n("iface"), translate("Interface"))
o.default = "eth1" o.default = "eth1"
o:depends({ [option_name("protocol")] = "_iface" }) o:depends({ [_n("protocol")] = "_iface" })
local nodes_table = {} local nodes_table = {}
local iface_table = {} local iface_table = {}
@ -94,11 +94,11 @@ end)
-- [[ 分流模块 ]] -- [[ 分流模块 ]]
if #nodes_table > 0 then if #nodes_table > 0 then
o = s:option(Flag, option_name("preproxy_enabled"), translate("Preproxy")) o = s:option(Flag, _n("preproxy_enabled"), translate("Preproxy"))
o:depends({ [option_name("protocol")] = "_shunt" }) o:depends({ [_n("protocol")] = "_shunt" })
o = s:option(ListValue, option_name("main_node"), string.format('<a style="color:red">%s</a>', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including <code>Default</code>) has a separate switch that controls whether this rule uses the pre-proxy or not.")) o = s:option(ListValue, _n("main_node"), string.format('<a style="color:red">%s</a>', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including <code>Default</code>) has a separate switch that controls whether this rule uses the pre-proxy or not."))
o:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true }) o:depends({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true })
for k, v in pairs(socks_list) do for k, v in pairs(socks_list) do
o:value(v.id, v.remark) o:value(v.id, v.remark)
end end
@ -108,16 +108,15 @@ if #nodes_table > 0 then
for k, v in pairs(nodes_table) do for k, v in pairs(nodes_table) do
o:value(v.id, v.remark) o:value(v.id, v.remark)
end end
o.default = "nil"
end end
uci:foreach(appname, "shunt_rules", function(e) uci:foreach(appname, "shunt_rules", function(e)
if e[".name"] and e.remarks then if e[".name"] and e.remarks then
o = s:option(ListValue, option_name(e[".name"]), string.format('* <a href="%s" target="_blank">%s</a>', api.url("shunt_rules", e[".name"]), e.remarks)) o = s:option(ListValue, _n(e[".name"]), string.format('* <a href="%s" target="_blank">%s</a>', api.url("shunt_rules", e[".name"]), e.remarks))
o:value("nil", translate("Close")) o:value("", translate("Close"))
o:value("_default", translate("Default")) o:value("_default", translate("Default"))
o:value("_direct", translate("Direct Connection")) o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole")) o:value("_blackhole", translate("Blackhole"))
o:depends({ [option_name("protocol")] = "_shunt" }) o:depends({ [_n("protocol")] = "_shunt" })
if #nodes_table > 0 then if #nodes_table > 0 then
for k, v in pairs(socks_list) do for k, v in pairs(socks_list) do
@ -126,28 +125,27 @@ uci:foreach(appname, "shunt_rules", function(e)
for k, v in pairs(iface_table) do for k, v in pairs(iface_table) do
o:value(v.id, v.remark) o:value(v.id, v.remark)
end end
local pt = s:option(ListValue, option_name(e[".name"] .. "_proxy_tag"), string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy"))) local pt = s:option(ListValue, _n(e[".name"] .. "_proxy_tag"), string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy")))
pt:value("nil", translate("Close")) pt:value("", translate("Close"))
pt:value("main", translate("Preproxy Node")) pt:value("main", translate("Preproxy Node"))
pt.default = "nil"
for k, v in pairs(nodes_table) do for k, v in pairs(nodes_table) do
o:value(v.id, v.remark) o:value(v.id, v.remark)
pt:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true, [option_name(e[".name"])] = v.id }) pt:depends({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true, [_n(e[".name"])] = v.id })
end end
end end
end end
end) end)
o = s:option(DummyValue, option_name("shunt_tips"), " ") o = s:option(DummyValue, _n("shunt_tips"), " ")
o.not_rewrite = true o.not_rewrite = true
o.rawhtml = true o.rawhtml = true
o.cfgvalue = function(t, n) o.cfgvalue = function(t, n)
return string.format('<a style="color: red" href="../rule">%s</a>', translate("No shunt rules? Click me to go to add.")) return string.format('<a style="color: red" href="../rule">%s</a>', translate("No shunt rules? Click me to go to add."))
end end
o:depends({ [option_name("protocol")] = "_shunt" }) o:depends({ [_n("protocol")] = "_shunt" })
local o = s:option(ListValue, option_name("default_node"), string.format('* <a style="color:red">%s</a>', translate("Default"))) local o = s:option(ListValue, _n("default_node"), string.format('* <a style="color:red">%s</a>', translate("Default")))
o:depends({ [option_name("protocol")] = "_shunt" }) o:depends({ [_n("protocol")] = "_shunt" })
o:value("_direct", translate("Direct Connection")) o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole")) o:value("_blackhole", translate("Blackhole"))
@ -158,61 +156,60 @@ if #nodes_table > 0 then
for k, v in pairs(iface_table) do for k, v in pairs(iface_table) do
o:value(v.id, v.remark) o:value(v.id, v.remark)
end end
local dpt = s:option(ListValue, option_name("default_proxy_tag"), string.format('* <a style="color:red">%s</a>', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node.")) local dpt = s:option(ListValue, _n("default_proxy_tag"), string.format('* <a style="color:red">%s</a>', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node."))
dpt:value("nil", translate("Close")) dpt:value("", translate("Close"))
dpt:value("main", translate("Preproxy Node")) dpt:value("main", translate("Preproxy Node"))
dpt.default = "nil"
for k, v in pairs(nodes_table) do for k, v in pairs(nodes_table) do
o:value(v.id, v.remark) o:value(v.id, v.remark)
dpt:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true, [option_name("default_node")] = v.id }) dpt:depends({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true, [_n("default_node")] = v.id })
end end
end end
-- [[ 分流模块 End ]] -- [[ 分流模块 End ]]
o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
o = s:option(Value, option_name("port"), translate("Port")) o = s:option(Value, _n("port"), translate("Port"))
o.datatype = "port" o.datatype = "port"
local protocols = s.fields[option_name("protocol")].keylist local protocols = s.fields[_n("protocol")].keylist
if #protocols > 0 then if #protocols > 0 then
for index, value in ipairs(protocols) do for index, value in ipairs(protocols) do
if not value:find("_") then if not value:find("_") then
s.fields[option_name("address")]:depends({ [option_name("protocol")] = value }) s.fields[_n("address")]:depends({ [_n("protocol")] = value })
s.fields[option_name("port")]:depends({ [option_name("protocol")] = value }) s.fields[_n("port")]:depends({ [_n("protocol")] = value })
end end
end end
end end
o = s:option(Value, option_name("username"), translate("Username")) o = s:option(Value, _n("username"), translate("Username"))
o:depends({ [option_name("protocol")] = "http" }) o:depends({ [_n("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o = s:option(Value, option_name("password"), translate("Password")) o = s:option(Value, _n("password"), translate("Password"))
o.password = true o.password = true
o:depends({ [option_name("protocol")] = "http" }) o:depends({ [_n("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "shadowsocksr" }) o:depends({ [_n("protocol")] = "shadowsocksr" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o = s:option(ListValue, option_name("security"), translate("Encrypt Method")) o = s:option(ListValue, _n("security"), translate("Encrypt Method"))
for a, t in ipairs(security_list) do o:value(t) end for a, t in ipairs(security_list) do o:value(t) end
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o = s:option(ListValue, option_name("ss_method"), translate("Encrypt Method")) o = s:option(ListValue, _n("ss_method"), translate("Encrypt Method"))
o.rewrite_option = "method" o.rewrite_option = "method"
for a, t in ipairs(ss_method_new_list) do o:value(t) end for a, t in ipairs(ss_method_new_list) do o:value(t) end
for a, t in ipairs(ss_method_old_list) do o:value(t) end for a, t in ipairs(ss_method_old_list) do o:value(t) end
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
if singbox_tags:find("with_shadowsocksr") then if singbox_tags:find("with_shadowsocksr") then
o = s:option(ListValue, option_name("ssr_method"), translate("Encrypt Method")) o = s:option(ListValue, _n("ssr_method"), translate("Encrypt Method"))
o.rewrite_option = "method" o.rewrite_option = "method"
for a, t in ipairs(ss_method_old_list) do o:value(t) end for a, t in ipairs(ss_method_old_list) do o:value(t) end
o:depends({ [option_name("protocol")] = "shadowsocksr" }) o:depends({ [_n("protocol")] = "shadowsocksr" })
local ssr_protocol_list = { local ssr_protocol_list = {
"origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple", "origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple",
@ -221,120 +218,120 @@ if singbox_tags:find("with_shadowsocksr") then
"auth_chain_d", "auth_chain_e", "auth_chain_f" "auth_chain_d", "auth_chain_e", "auth_chain_f"
} }
o = s:option(ListValue, option_name("ssr_protocol"), translate("Protocol")) o = s:option(ListValue, _n("ssr_protocol"), translate("Protocol"))
for a, t in ipairs(ssr_protocol_list) do o:value(t) end for a, t in ipairs(ssr_protocol_list) do o:value(t) end
o:depends({ [option_name("protocol")] = "shadowsocksr" }) o:depends({ [_n("protocol")] = "shadowsocksr" })
o = s:option(Value, option_name("ssr_protocol_param"), translate("Protocol_param")) o = s:option(Value, _n("ssr_protocol_param"), translate("Protocol_param"))
o:depends({ [option_name("protocol")] = "shadowsocksr" }) o:depends({ [_n("protocol")] = "shadowsocksr" })
local ssr_obfs_list = { local ssr_obfs_list = {
"plain", "http_simple", "http_post", "random_head", "tls_simple", "plain", "http_simple", "http_post", "random_head", "tls_simple",
"tls1.0_session_auth", "tls1.2_ticket_auth" "tls1.0_session_auth", "tls1.2_ticket_auth"
} }
o = s:option(ListValue, option_name("ssr_obfs"), translate("Obfs")) o = s:option(ListValue, _n("ssr_obfs"), translate("Obfs"))
for a, t in ipairs(ssr_obfs_list) do o:value(t) end for a, t in ipairs(ssr_obfs_list) do o:value(t) end
o:depends({ [option_name("protocol")] = "shadowsocksr" }) o:depends({ [_n("protocol")] = "shadowsocksr" })
o = s:option(Value, option_name("ssr_obfs_param"), translate("Obfs_param")) o = s:option(Value, _n("ssr_obfs_param"), translate("Obfs_param"))
o:depends({ [option_name("protocol")] = "shadowsocksr" }) o:depends({ [_n("protocol")] = "shadowsocksr" })
end end
o = s:option(Flag, option_name("uot"), translate("UDP over TCP")) o = s:option(Flag, _n("uot"), translate("UDP over TCP"))
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(Value, option_name("uuid"), translate("ID")) o = s:option(Value, _n("uuid"), translate("ID"))
o.password = true o.password = true
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o = s:option(Value, option_name("alter_id"), "Alter ID") o = s:option(Value, _n("alter_id"), "Alter ID")
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = "0" o.default = "0"
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o = s:option(Flag, option_name("global_padding"), "global_padding", translate("Protocol parameter. Will waste traffic randomly if enabled.")) o = s:option(Flag, _n("global_padding"), "global_padding", translate("Protocol parameter. Will waste traffic randomly if enabled."))
o.default = "0" o.default = "0"
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o = s:option(Flag, option_name("authenticated_length"), "authenticated_length", translate("Protocol parameter. Enable length block encryption.")) o = s:option(Flag, _n("authenticated_length"), "authenticated_length", translate("Protocol parameter. Enable length block encryption."))
o.default = "0" o.default = "0"
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o = s:option(ListValue, option_name("flow"), translate("flow")) o = s:option(ListValue, _n("flow"), translate("flow"))
o.default = "" o.default = ""
o:value("", translate("Disable")) o:value("", translate("Disable"))
o:value("xtls-rprx-vision") o:value("xtls-rprx-vision")
o:depends({ [option_name("protocol")] = "vless", [option_name("tls")] = true }) o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true })
if singbox_tags:find("with_quic") then if singbox_tags:find("with_quic") then
o = s:option(Value, option_name("hysteria_obfs"), translate("Obfs Password")) o = s:option(Value, _n("hysteria_obfs"), translate("Obfs Password"))
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(ListValue, option_name("hysteria_auth_type"), translate("Auth Type")) o = s:option(ListValue, _n("hysteria_auth_type"), translate("Auth Type"))
o:value("disable", translate("Disable")) o:value("disable", translate("Disable"))
o:value("string", translate("STRING")) o:value("string", translate("STRING"))
o:value("base64", translate("BASE64")) o:value("base64", translate("BASE64"))
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_auth_password"), translate("Auth Password")) o = s:option(Value, _n("hysteria_auth_password"), translate("Auth Password"))
o.password = true o.password = true
o:depends({ [option_name("protocol")] = "hysteria", [option_name("hysteria_auth_type")] = "string"}) o:depends({ [_n("protocol")] = "hysteria", [_n("hysteria_auth_type")] = "string"})
o:depends({ [option_name("protocol")] = "hysteria", [option_name("hysteria_auth_type")] = "base64"}) o:depends({ [_n("protocol")] = "hysteria", [_n("hysteria_auth_type")] = "base64"})
o = s:option(Value, option_name("hysteria_up_mbps"), translate("Max upload Mbps")) o = s:option(Value, _n("hysteria_up_mbps"), translate("Max upload Mbps"))
o.default = "10" o.default = "10"
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_down_mbps"), translate("Max download Mbps")) o = s:option(Value, _n("hysteria_down_mbps"), translate("Max download Mbps"))
o.default = "50" o.default = "50"
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_recv_window_conn"), translate("QUIC stream receive window")) o = s:option(Value, _n("hysteria_recv_window_conn"), translate("QUIC stream receive window"))
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_recv_window"), translate("QUIC connection receive window")) o = s:option(Value, _n("hysteria_recv_window"), translate("QUIC connection receive window"))
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Flag, option_name("hysteria_disable_mtu_discovery"), translate("Disable MTU detection")) o = s:option(Flag, _n("hysteria_disable_mtu_discovery"), translate("Disable MTU detection"))
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_alpn"), translate("QUIC TLS ALPN")) o = s:option(Value, _n("hysteria_alpn"), translate("QUIC TLS ALPN"))
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
end end
if singbox_tags:find("with_quic") then if singbox_tags:find("with_quic") then
o = s:option(ListValue, option_name("tuic_congestion_control"), translate("Congestion control algorithm")) o = s:option(ListValue, _n("tuic_congestion_control"), translate("Congestion control algorithm"))
o.default = "cubic" o.default = "cubic"
o:value("bbr", translate("BBR")) o:value("bbr", translate("BBR"))
o:value("cubic", translate("CUBIC")) o:value("cubic", translate("CUBIC"))
o:value("new_reno", translate("New Reno")) o:value("new_reno", translate("New Reno"))
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o = s:option(ListValue, option_name("tuic_udp_relay_mode"), translate("UDP relay mode")) o = s:option(ListValue, _n("tuic_udp_relay_mode"), translate("UDP relay mode"))
o.default = "native" o.default = "native"
o:value("native", translate("native")) o:value("native", translate("native"))
o:value("quic", translate("QUIC")) o:value("quic", translate("QUIC"))
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
--[[ --[[
o = s:option(Flag, option_name("tuic_udp_over_stream"), translate("UDP over stream")) o = s:option(Flag, _n("tuic_udp_over_stream"), translate("UDP over stream"))
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
]]-- ]]--
o = s:option(Flag, option_name("tuic_zero_rtt_handshake"), translate("Enable 0-RTT QUIC handshake")) o = s:option(Flag, _n("tuic_zero_rtt_handshake"), translate("Enable 0-RTT QUIC handshake"))
o.default = 0 o.default = 0
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o = s:option(Value, option_name("tuic_heartbeat"), translate("Heartbeat interval(second)")) o = s:option(Value, _n("tuic_heartbeat"), translate("Heartbeat interval(second)"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = "3" o.default = "3"
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o = s:option(ListValue, option_name("tuic_alpn"), translate("QUIC TLS ALPN")) o = s:option(ListValue, _n("tuic_alpn"), translate("QUIC TLS ALPN"))
o.default = "default" o.default = "default"
o:value("default", translate("Default")) o:value("default", translate("Default"))
o:value("h3") o:value("h3")
@ -343,38 +340,38 @@ if singbox_tags:find("with_quic") then
o:value("http/1.1") o:value("http/1.1")
o:value("h2,http/1.1") o:value("h2,http/1.1")
o:value("h3,h2,http/1.1") o:value("h3,h2,http/1.1")
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
end end
if singbox_tags:find("with_quic") then if singbox_tags:find("with_quic") then
o = s:option(Value, option_name("hysteria2_up_mbps"), translate("Max upload Mbps")) o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, option_name("hysteria2_down_mbps"), translate("Max download Mbps")) o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps"))
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(ListValue, option_name("hysteria2_obfs_type"), translate("Obfs Type")) o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type"))
o:value("", translate("Disable")) o:value("", translate("Disable"))
o:value("salamander") o:value("salamander")
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, option_name("hysteria2_obfs_password"), translate("Obfs Password")) o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, option_name("hysteria2_auth_password"), translate("Auth Password")) o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password"))
o.password = true o.password = true
o:depends({ [option_name("protocol")] = "hysteria2"}) o:depends({ [_n("protocol")] = "hysteria2"})
end end
o = s:option(Flag, option_name("tls"), translate("TLS")) o = s:option(Flag, _n("tls"), translate("TLS"))
o.default = 0 o.default = 0
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "http" }) o:depends({ [_n("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(ListValue, option_name("alpn"), translate("alpn")) o = s:option(ListValue, _n("alpn"), translate("alpn"))
o.default = "default" o.default = "default"
o:value("default", translate("Default")) o:value("default", translate("Default"))
o:value("h3") o:value("h3")
@ -383,36 +380,36 @@ o:value("h3,h2")
o:value("http/1.1") o:value("http/1.1")
o:value("h2,http/1.1") o:value("h2,http/1.1")
o:value("h3,h2,http/1.1") o:value("h3,h2,http/1.1")
o:depends({ [option_name("tls")] = true }) o:depends({ [_n("tls")] = true })
o = s:option(Value, option_name("tls_serverName"), translate("Domain")) o = s:option(Value, _n("tls_serverName"), translate("Domain"))
o:depends({ [option_name("tls")] = true }) o:depends({ [_n("tls")] = true })
o:depends({ [option_name("protocol")] = "hysteria"}) o:depends({ [_n("protocol")] = "hysteria"})
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(Flag, option_name("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped."))
o.default = "0" o.default = "0"
o:depends({ [option_name("tls")] = true }) o:depends({ [_n("tls")] = true })
o:depends({ [option_name("protocol")] = "hysteria"}) o:depends({ [_n("protocol")] = "hysteria"})
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
if singbox_tags:find("with_ech") then if singbox_tags:find("with_ech") then
o = s:option(Flag, option_name("ech"), translate("ECH")) o = s:option(Flag, _n("ech"), translate("ECH"))
o.default = "0" o.default = "0"
o:depends({ [option_name("tls")] = true, [option_name("flow")] = "", [option_name("reality")] = false }) o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(TextValue, option_name("ech_config"), translate("ECH Config")) o = s:option(TextValue, _n("ech_config"), translate("ECH Config"))
o.default = "" o.default = ""
o.rows = 5 o.rows = 5
o.wrap = "off" o.wrap = "off"
o:depends({ [option_name("ech")] = true }) o:depends({ [_n("ech")] = true })
o.validate = function(self, value) o.validate = function(self, value)
value = value:gsub("^%s+", ""):gsub("%s+$","\n"):gsub("\r\n","\n"):gsub("[ \t]*\n[ \t]*", "\n") value = value:gsub("^%s+", ""):gsub("%s+$","\n"):gsub("\r\n","\n"):gsub("[ \t]*\n[ \t]*", "\n")
value = value:gsub("^%s*\n", "") value = value:gsub("^%s*\n", "")
@ -422,21 +419,21 @@ if singbox_tags:find("with_ech") then
return value return value
end end
o = s:option(Flag, option_name("pq_signature_schemes_enabled"), translate("PQ signature schemes")) o = s:option(Flag, _n("pq_signature_schemes_enabled"), translate("PQ signature schemes"))
o.default = "0" o.default = "0"
o:depends({ [option_name("ech")] = true }) o:depends({ [_n("ech")] = true })
o = s:option(Flag, option_name("dynamic_record_sizing_disabled"), translate("Disable adaptive sizing of TLS records")) o = s:option(Flag, _n("dynamic_record_sizing_disabled"), translate("Disable adaptive sizing of TLS records"))
o.default = "0" o.default = "0"
o:depends({ [option_name("ech")] = true }) o:depends({ [_n("ech")] = true })
end end
if singbox_tags:find("with_utls") then if singbox_tags:find("with_utls") then
o = s:option(Flag, option_name("utls"), translate("uTLS")) o = s:option(Flag, _n("utls"), translate("uTLS"))
o.default = "0" o.default = "0"
o:depends({ [option_name("tls")] = true }) o:depends({ [_n("tls")] = true })
o = s:option(ListValue, option_name("fingerprint"), translate("Finger Print")) o = s:option(ListValue, _n("fingerprint"), translate("Finger Print"))
o:value("chrome") o:value("chrome")
o:value("firefox") o:value("firefox")
o:value("edge") o:value("edge")
@ -448,25 +445,25 @@ if singbox_tags:find("with_utls") then
o:value("random") o:value("random")
-- o:value("randomized") -- o:value("randomized")
o.default = "chrome" o.default = "chrome"
o:depends({ [option_name("tls")] = true, [option_name("utls")] = true }) o:depends({ [_n("tls")] = true, [_n("utls")] = true })
-- [[ REALITY部分 ]] -- -- [[ REALITY部分 ]] --
o = s:option(Flag, option_name("reality"), translate("REALITY")) o = s:option(Flag, _n("reality"), translate("REALITY"))
o.default = 0 o.default = 0
o:depends({ [option_name("protocol")] = "vless", [option_name("utls")] = true }) o:depends({ [_n("protocol")] = "vless", [_n("utls")] = true })
o:depends({ [option_name("protocol")] = "vmess", [option_name("utls")] = true }) o:depends({ [_n("protocol")] = "vmess", [_n("utls")] = true })
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("utls")] = true }) o:depends({ [_n("protocol")] = "shadowsocks", [_n("utls")] = true })
o:depends({ [option_name("protocol")] = "socks", [option_name("utls")] = true }) o:depends({ [_n("protocol")] = "socks", [_n("utls")] = true })
o:depends({ [option_name("protocol")] = "trojan", [option_name("utls")] = true }) o:depends({ [_n("protocol")] = "trojan", [_n("utls")] = true })
o = s:option(Value, option_name("reality_publicKey"), translate("Public Key")) o = s:option(Value, _n("reality_publicKey"), translate("Public Key"))
o:depends({ [option_name("utls")] = true, [option_name("reality")] = true }) o:depends({ [_n("utls")] = true, [_n("reality")] = true })
o = s:option(Value, option_name("reality_shortId"), translate("Short Id")) o = s:option(Value, _n("reality_shortId"), translate("Short Id"))
o:depends({ [option_name("utls")] = true, [option_name("reality")] = true }) o:depends({ [_n("utls")] = true, [_n("reality")] = true })
end end
o = s:option(ListValue, option_name("transport"), translate("Transport")) o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("tcp", "TCP") o:value("tcp", "TCP")
o:value("http", "HTTP") o:value("http", "HTTP")
o:value("ws", "WebSocket") o:value("ws", "WebSocket")
@ -478,158 +475,158 @@ if singbox_tags:find("with_grpc") then
o:value("grpc", "gRPC") o:value("grpc", "gRPC")
else o:value("grpc", "gRPC-lite") else o:value("grpc", "gRPC-lite")
end end
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
if singbox_tags:find("with_wireguard") then if singbox_tags:find("with_wireguard") then
o = s:option(Value, option_name("wireguard_public_key"), translate("Public Key")) o = s:option(Value, _n("wireguard_public_key"), translate("Public Key"))
o:depends({ [option_name("protocol")] = "wireguard" }) o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(Value, option_name("wireguard_secret_key"), translate("Private Key")) o = s:option(Value, _n("wireguard_secret_key"), translate("Private Key"))
o:depends({ [option_name("protocol")] = "wireguard" }) o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(Value, option_name("wireguard_preSharedKey"), translate("Pre shared key")) o = s:option(Value, _n("wireguard_preSharedKey"), translate("Pre shared key"))
o:depends({ [option_name("protocol")] = "wireguard" }) o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(DynamicList, option_name("wireguard_local_address"), translate("Local Address")) o = s:option(DynamicList, _n("wireguard_local_address"), translate("Local Address"))
o:depends({ [option_name("protocol")] = "wireguard" }) o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(Value, option_name("wireguard_mtu"), translate("MTU")) o = s:option(Value, _n("wireguard_mtu"), translate("MTU"))
o.default = "1420" o.default = "1420"
o:depends({ [option_name("protocol")] = "wireguard" }) o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(Value, option_name("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings.")) o = s:option(Value, _n("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings."))
o:depends({ [option_name("protocol")] = "wireguard" }) o:depends({ [_n("protocol")] = "wireguard" })
end end
-- [[ HTTP部分 ]]-- -- [[ HTTP部分 ]]--
o = s:option(Value, option_name("http_host"), translate("HTTP Host")) o = s:option(Value, _n("http_host"), translate("HTTP Host"))
o:depends({ [option_name("transport")] = "http" }) o:depends({ [_n("transport")] = "http" })
o = s:option(Value, option_name("http_path"), translate("HTTP Path")) o = s:option(Value, _n("http_path"), translate("HTTP Path"))
o.placeholder = "/" o.placeholder = "/"
o:depends({ [option_name("transport")] = "http" }) o:depends({ [_n("transport")] = "http" })
o = s:option(Flag, option_name("http_h2_health_check"), translate("Health check")) o = s:option(Flag, _n("http_h2_health_check"), translate("Health check"))
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "http" }) o:depends({ [_n("tls")] = true, [_n("transport")] = "http" })
o = s:option(Value, option_name("http_h2_read_idle_timeout"), translate("Idle timeout")) o = s:option(Value, _n("http_h2_read_idle_timeout"), translate("Idle timeout"))
o.default = "10" o.default = "10"
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "http", [option_name("http_h2_health_check")] = true }) o:depends({ [_n("tls")] = true, [_n("transport")] = "http", [_n("http_h2_health_check")] = true })
o = s:option(Value, option_name("http_h2_health_check_timeout"), translate("Health check timeout")) o = s:option(Value, _n("http_h2_health_check_timeout"), translate("Health check timeout"))
o.default = "15" o.default = "15"
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "http", [option_name("http_h2_health_check")] = true }) o:depends({ [_n("tls")] = true, [_n("transport")] = "http", [_n("http_h2_health_check")] = true })
-- [[ WebSocket部分 ]]-- -- [[ WebSocket部分 ]]--
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host")) o = s:option(Value, _n("ws_host"), translate("WebSocket Host"))
o:depends({ [option_name("transport")] = "ws" }) o:depends({ [_n("transport")] = "ws" })
o = s:option(Value, option_name("ws_path"), translate("WebSocket Path")) o = s:option(Value, _n("ws_path"), translate("WebSocket Path"))
o.placeholder = "/" o.placeholder = "/"
o:depends({ [option_name("transport")] = "ws" }) o:depends({ [_n("transport")] = "ws" })
o = s:option(Flag, option_name("ws_enableEarlyData"), translate("Enable early data")) o = s:option(Flag, _n("ws_enableEarlyData"), translate("Enable early data"))
o:depends({ [option_name("transport")] = "ws" }) o:depends({ [_n("transport")] = "ws" })
o = s:option(Value, option_name("ws_maxEarlyData"), translate("Early data length")) o = s:option(Value, _n("ws_maxEarlyData"), translate("Early data length"))
o.default = "1024" o.default = "1024"
o:depends({ [option_name("ws_enableEarlyData")] = true }) o:depends({ [_n("ws_enableEarlyData")] = true })
o = s:option(Value, option_name("ws_earlyDataHeaderName"), translate("Early data header name"), translate("Recommended value: Sec-WebSocket-Protocol")) o = s:option(Value, _n("ws_earlyDataHeaderName"), translate("Early data header name"), translate("Recommended value: Sec-WebSocket-Protocol"))
o:depends({ [option_name("ws_enableEarlyData")] = true }) o:depends({ [_n("ws_enableEarlyData")] = true })
-- [[ HTTPUpgrade部分 ]]-- -- [[ HTTPUpgrade部分 ]]--
o = s:option(Value, option_name("httpupgrade_host"), translate("HTTPUpgrade Host")) o = s:option(Value, _n("httpupgrade_host"), translate("HTTPUpgrade Host"))
o:depends({ [option_name("transport")] = "httpupgrade" }) o:depends({ [_n("transport")] = "httpupgrade" })
o = s:option(Value, option_name("httpupgrade_path"), translate("HTTPUpgrade Path")) o = s:option(Value, _n("httpupgrade_path"), translate("HTTPUpgrade Path"))
o.placeholder = "/" o.placeholder = "/"
o:depends({ [option_name("transport")] = "httpupgrade" }) o:depends({ [_n("transport")] = "httpupgrade" })
-- [[ gRPC部分 ]]-- -- [[ gRPC部分 ]]--
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName") o = s:option(Value, _n("grpc_serviceName"), "ServiceName")
o:depends({ [option_name("transport")] = "grpc" }) o:depends({ [_n("transport")] = "grpc" })
o = s:option(Flag, option_name("grpc_health_check"), translate("Health check")) o = s:option(Flag, _n("grpc_health_check"), translate("Health check"))
o:depends({ [option_name("transport")] = "grpc" }) o:depends({ [_n("transport")] = "grpc" })
o = s:option(Value, option_name("grpc_idle_timeout"), translate("Idle timeout")) o = s:option(Value, _n("grpc_idle_timeout"), translate("Idle timeout"))
o.default = "10" o.default = "10"
o:depends({ [option_name("grpc_health_check")] = true }) o:depends({ [_n("grpc_health_check")] = true })
o = s:option(Value, option_name("grpc_health_check_timeout"), translate("Health check timeout")) o = s:option(Value, _n("grpc_health_check_timeout"), translate("Health check timeout"))
o.default = "20" o.default = "20"
o:depends({ [option_name("grpc_health_check")] = true }) o:depends({ [_n("grpc_health_check")] = true })
o = s:option(Flag, option_name("grpc_permit_without_stream"), translate("Permit without stream")) o = s:option(Flag, _n("grpc_permit_without_stream"), translate("Permit without stream"))
o.default = "0" o.default = "0"
o:depends({ [option_name("grpc_health_check")] = true }) o:depends({ [_n("grpc_health_check")] = true })
-- [[ Mux ]]-- -- [[ Mux ]]--
o = s:option(Flag, option_name("mux"), translate("Mux")) o = s:option(Flag, _n("mux"), translate("Mux"))
o.rmempty = false o.rmempty = false
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless", [option_name("flow")] = "" }) o:depends({ [_n("protocol")] = "vless", [_n("flow")] = "" })
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("uot")] = "" }) o:depends({ [_n("protocol")] = "shadowsocks", [_n("uot")] = "" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
o = s:option(ListValue, option_name("mux_type"), translate("Mux")) o = s:option(ListValue, _n("mux_type"), translate("Mux"))
o:value("smux") o:value("smux")
o:value("yamux") o:value("yamux")
o:value("h2mux") o:value("h2mux")
o:depends({ [option_name("mux")] = true }) o:depends({ [_n("mux")] = true })
o = s:option(Value, option_name("mux_concurrency"), translate("Mux concurrency")) o = s:option(Value, _n("mux_concurrency"), translate("Mux concurrency"))
o.default = 4 o.default = 4
o:depends({ [option_name("mux")] = true, [option_name("tcpbrutal")] = false }) o:depends({ [_n("mux")] = true, [_n("tcpbrutal")] = false })
o = s:option(Flag, option_name("mux_padding"), translate("Padding")) o = s:option(Flag, _n("mux_padding"), translate("Padding"))
o.default = 0 o.default = 0
o:depends({ [option_name("mux")] = true }) o:depends({ [_n("mux")] = true })
-- [[ TCP Brutal ]]-- -- [[ TCP Brutal ]]--
o = s:option(Flag, option_name("tcpbrutal"), translate("TCP Brutal")) o = s:option(Flag, _n("tcpbrutal"), translate("TCP Brutal"))
o.default = 0 o.default = 0
o:depends({ [option_name("mux")] = true }) o:depends({ [_n("mux")] = true })
o = s:option(Value, option_name("tcpbrutal_up_mbps"), translate("Max upload Mbps")) o = s:option(Value, _n("tcpbrutal_up_mbps"), translate("Max upload Mbps"))
o.default = "10" o.default = "10"
o:depends({ [option_name("tcpbrutal")] = true }) o:depends({ [_n("tcpbrutal")] = true })
o = s:option(Value, option_name("tcpbrutal_down_mbps"), translate("Max download Mbps")) o = s:option(Value, _n("tcpbrutal_down_mbps"), translate("Max download Mbps"))
o.default = "50" o.default = "50"
o:depends({ [option_name("tcpbrutal")] = true }) o:depends({ [_n("tcpbrutal")] = true })
o = s:option(Flag, option_name("shadowtls"), "ShadowTLS") o = s:option(Flag, _n("shadowtls"), "ShadowTLS")
o.default = 0 o.default = 0
o:depends({ [option_name("protocol")] = "vmess", [option_name("tls")] = false }) o:depends({ [_n("protocol")] = "vmess", [_n("tls")] = false })
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("tls")] = false }) o:depends({ [_n("protocol")] = "shadowsocks", [_n("tls")] = false })
o = s:option(ListValue, option_name("shadowtls_version"), "ShadowTLS " .. translate("Version")) o = s:option(ListValue, _n("shadowtls_version"), "ShadowTLS " .. translate("Version"))
o.default = "1" o.default = "1"
o:value("1", "ShadowTLS v1") o:value("1", "ShadowTLS v1")
o:value("2", "ShadowTLS v2") o:value("2", "ShadowTLS v2")
o:value("3", "ShadowTLS v3") o:value("3", "ShadowTLS v3")
o:depends({ [option_name("shadowtls")] = true }) o:depends({ [_n("shadowtls")] = true })
o = s:option(Value, option_name("shadowtls_password"), "ShadowTLS " .. translate("Password")) o = s:option(Value, _n("shadowtls_password"), "ShadowTLS " .. translate("Password"))
o.password = true o.password = true
o:depends({ [option_name("shadowtls")] = true, [option_name("shadowtls_version")] = "2" }) o:depends({ [_n("shadowtls")] = true, [_n("shadowtls_version")] = "2" })
o:depends({ [option_name("shadowtls")] = true, [option_name("shadowtls_version")] = "3" }) o:depends({ [_n("shadowtls")] = true, [_n("shadowtls_version")] = "3" })
o = s:option(Value, option_name("shadowtls_serverName"), "ShadowTLS " .. translate("Domain")) o = s:option(Value, _n("shadowtls_serverName"), "ShadowTLS " .. translate("Domain"))
o:depends({ [option_name("shadowtls")] = true }) o:depends({ [_n("shadowtls")] = true })
if singbox_tags:find("with_utls") then if singbox_tags:find("with_utls") then
o = s:option(Flag, option_name("shadowtls_utls"), "ShadowTLS " .. translate("uTLS")) o = s:option(Flag, _n("shadowtls_utls"), "ShadowTLS " .. translate("uTLS"))
o.default = "0" o.default = "0"
o:depends({ [option_name("shadowtls")] = true }) o:depends({ [_n("shadowtls")] = true })
o = s:option(ListValue, option_name("shadowtls_fingerprint"), "ShadowTLS " .. translate("Finger Print")) o = s:option(ListValue, _n("shadowtls_fingerprint"), "ShadowTLS " .. translate("Finger Print"))
o:value("chrome") o:value("chrome")
o:value("firefox") o:value("firefox")
o:value("edge") o:value("edge")
@ -641,62 +638,62 @@ if singbox_tags:find("with_utls") then
o:value("random") o:value("random")
-- o:value("randomized") -- o:value("randomized")
o.default = "chrome" o.default = "chrome"
o:depends({ [option_name("shadowtls")] = true, [option_name("shadowtls_utls")] = true }) o:depends({ [_n("shadowtls")] = true, [_n("shadowtls_utls")] = true })
end end
-- [[ SIP003 plugin ]]-- -- [[ SIP003 plugin ]]--
o = s:option(Flag, option_name("plugin_enabled"), translate("plugin")) o = s:option(Flag, _n("plugin_enabled"), translate("plugin"))
o.default = 0 o.default = 0
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(ListValue, option_name("plugin"), "SIP003 " .. translate("plugin")) o = s:option(ListValue, _n("plugin"), "SIP003 " .. translate("plugin"))
o.default = "obfs-local" o.default = "obfs-local"
o:depends({ [option_name("plugin_enabled")] = true }) o:depends({ [_n("plugin_enabled")] = true })
o:value("obfs-local") o:value("obfs-local")
o:value("v2ray-plugin") o:value("v2ray-plugin")
o = s:option(Value, option_name("plugin_opts"), translate("opts")) o = s:option(Value, _n("plugin_opts"), translate("opts"))
o:depends({ [option_name("plugin_enabled")] = true }) o:depends({ [_n("plugin_enabled")] = true })
o = s:option(ListValue, option_name("domain_strategy"), translate("Domain Strategy"), translate("If is domain name, The requested domain name will be resolved to IP before connect.")) o = s:option(ListValue, _n("domain_strategy"), translate("Domain Strategy"), translate("If is domain name, The requested domain name will be resolved to IP before connect."))
o.default = "" o.default = ""
o:value("", translate("Auto")) o:value("", translate("Auto"))
o:value("prefer_ipv4", translate("Prefer IPv4")) o:value("prefer_ipv4", translate("Prefer IPv4"))
o:value("prefer_ipv6", translate("Prefer IPv6")) o:value("prefer_ipv6", translate("Prefer IPv6"))
o:value("ipv4_only", translate("IPv4 Only")) o:value("ipv4_only", translate("IPv4 Only"))
o:value("ipv6_only", translate("IPv6 Only")) o:value("ipv6_only", translate("IPv6 Only"))
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "http" }) o:depends({ [_n("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "shadowsocksr" }) o:depends({ [_n("protocol")] = "shadowsocksr" })
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
o:depends({ [option_name("protocol")] = "wireguard" }) o:depends({ [_n("protocol")] = "wireguard" })
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(ListValue, option_name("chain_proxy"), translate("Chain Proxy")) o = s:option(ListValue, _n("chain_proxy"), translate("Chain Proxy"))
o:value("", translate("Close(Not use)")) o:value("", translate("Close(Not use)"))
o:value("1", translate("Preproxy Node")) o:value("1", translate("Preproxy Node"))
o:value("2", translate("Landing Node")) o:value("2", translate("Landing Node"))
for i, v in ipairs(s.fields[option_name("protocol")].keylist) do for i, v in ipairs(s.fields[_n("protocol")].keylist) do
if not v:find("_") then if not v:find("_") then
o:depends({ [option_name("protocol")] = v }) o:depends({ [_n("protocol")] = v })
end end
end end
o = s:option(ListValue, option_name("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy.")) o = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
o:depends({ [option_name("chain_proxy")] = "1" }) o:depends({ [_n("chain_proxy")] = "1" })
o = s:option(ListValue, option_name("to_node"), translate("Landing Node"), translate("Only support a layer of proxy.")) o = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
o:depends({ [option_name("chain_proxy")] = "2" }) o:depends({ [_n("chain_proxy")] = "2" })
for k, v in pairs(nodes_table) do for k, v in pairs(nodes_table) do
if v.type == "sing-box" and v.id ~= arg[1] then if v.type == "sing-box" and v.id ~= arg[1] then
s.fields[option_name("preproxy_node")]:value(v.id, v.remark) s.fields[_n("preproxy_node")]:value(v.id, v.remark)
s.fields[option_name("to_node")]:value(v.id, v.remark) s.fields[_n("to_node")]:value(v.id, v.remark)
end end
end end

View File

@ -10,7 +10,7 @@ local type_name = "SS-Rust"
local option_prefix = "ssrust_" local option_prefix = "ssrust_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -24,34 +24,34 @@ local ssrust_encrypt_method_list = {
s.fields["type"]:value(type_name, translate("Shadowsocks Rust")) s.fields["type"]:value(type_name, translate("Shadowsocks Rust"))
o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
o = s:option(Value, option_name("port"), translate("Port")) o = s:option(Value, _n("port"), translate("Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(Value, option_name("password"), translate("Password")) o = s:option(Value, _n("password"), translate("Password"))
o.password = true o.password = true
o = s:option(Value, option_name("method"), translate("Encrypt Method")) o = s:option(Value, _n("method"), translate("Encrypt Method"))
for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end
o = s:option(Value, option_name("timeout"), translate("Connection Timeout")) o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = 300 o.default = 300
o = s:option(ListValue, option_name("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required")) o = s:option(ListValue, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required"))
o:value("false") o:value("false")
o:value("true") o:value("true")
o = s:option(ListValue, option_name("plugin"), translate("plugin")) o = s:option(ListValue, _n("plugin"), translate("plugin"))
o:value("none", translate("none")) o:value("none", translate("none"))
if api.is_finded("xray-plugin") then o:value("xray-plugin") end if api.is_finded("xray-plugin") then o:value("xray-plugin") end
if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end
if api.is_finded("obfs-local") then o:value("obfs-local") end if api.is_finded("obfs-local") then o:value("obfs-local") end
o = s:option(Value, option_name("plugin_opts"), translate("opts")) o = s:option(Value, _n("plugin_opts"), translate("opts"))
o:depends({ [option_name("plugin")] = "xray-plugin"}) o:depends({ [_n("plugin")] = "xray-plugin"})
o:depends({ [option_name("plugin")] = "v2ray-plugin"}) o:depends({ [_n("plugin")] = "v2ray-plugin"})
o:depends({ [option_name("plugin")] = "obfs-local"}) o:depends({ [_n("plugin")] = "obfs-local"})
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -10,7 +10,7 @@ local type_name = "SS"
local option_prefix = "ss_" local option_prefix = "ss_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -25,34 +25,34 @@ local ss_encrypt_method_list = {
s.fields["type"]:value(type_name, translate("Shadowsocks Libev")) s.fields["type"]:value(type_name, translate("Shadowsocks Libev"))
o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
o = s:option(Value, option_name("port"), translate("Port")) o = s:option(Value, _n("port"), translate("Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(Value, option_name("password"), translate("Password")) o = s:option(Value, _n("password"), translate("Password"))
o.password = true o.password = true
o = s:option(Value, option_name("method"), translate("Encrypt Method")) o = s:option(Value, _n("method"), translate("Encrypt Method"))
for a, t in ipairs(ss_encrypt_method_list) do o:value(t) end for a, t in ipairs(ss_encrypt_method_list) do o:value(t) end
o = s:option(Value, option_name("timeout"), translate("Connection Timeout")) o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = 300 o.default = 300
o = s:option(ListValue, option_name("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required")) o = s:option(ListValue, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required"))
o:value("false") o:value("false")
o:value("true") o:value("true")
o = s:option(ListValue, option_name("plugin"), translate("plugin")) o = s:option(ListValue, _n("plugin"), translate("plugin"))
o:value("none", translate("none")) o:value("none", translate("none"))
if api.is_finded("xray-plugin") then o:value("xray-plugin") end if api.is_finded("xray-plugin") then o:value("xray-plugin") end
if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end
if api.is_finded("obfs-local") then o:value("obfs-local") end if api.is_finded("obfs-local") then o:value("obfs-local") end
o = s:option(Value, option_name("plugin_opts"), translate("opts")) o = s:option(Value, _n("plugin_opts"), translate("opts"))
o:depends({ [option_name("plugin")] = "xray-plugin"}) o:depends({ [_n("plugin")] = "xray-plugin"})
o:depends({ [option_name("plugin")] = "v2ray-plugin"}) o:depends({ [_n("plugin")] = "v2ray-plugin"})
o:depends({ [option_name("plugin")] = "obfs-local"}) o:depends({ [_n("plugin")] = "obfs-local"})
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -10,7 +10,7 @@ local type_name = "SSR"
local option_prefix = "ssr_" local option_prefix = "ssr_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -37,32 +37,32 @@ local ssr_obfs_list = {
s.fields["type"]:value(type_name, translate("ShadowsocksR Libev")) s.fields["type"]:value(type_name, translate("ShadowsocksR Libev"))
o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
o = s:option(Value, option_name("port"), translate("Port")) o = s:option(Value, _n("port"), translate("Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(Value, option_name("password"), translate("Password")) o = s:option(Value, _n("password"), translate("Password"))
o.password = true o.password = true
o = s:option(ListValue, option_name("method"), translate("Encrypt Method")) o = s:option(ListValue, _n("method"), translate("Encrypt Method"))
for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end
o = s:option(ListValue, option_name("protocol"), translate("Protocol")) o = s:option(ListValue, _n("protocol"), translate("Protocol"))
for a, t in ipairs(ssr_protocol_list) do o:value(t) end for a, t in ipairs(ssr_protocol_list) do o:value(t) end
o = s:option(Value, option_name("protocol_param"), translate("Protocol_param")) o = s:option(Value, _n("protocol_param"), translate("Protocol_param"))
o = s:option(ListValue, option_name("obfs"), translate("Obfs")) o = s:option(ListValue, _n("obfs"), translate("Obfs"))
for a, t in ipairs(ssr_obfs_list) do o:value(t) end for a, t in ipairs(ssr_obfs_list) do o:value(t) end
o = s:option(Value, option_name("obfs_param"), translate("Obfs_param")) o = s:option(Value, _n("obfs_param"), translate("Obfs_param"))
o = s:option(Value, option_name("timeout"), translate("Connection Timeout")) o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = 300 o.default = 300
o = s:option(ListValue, option_name("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required")) o = s:option(ListValue, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required"))
o:value("false") o:value("false")
o:value("true") o:value("true")

View File

@ -10,7 +10,7 @@ local type_name = "Trojan-Plus"
local option_prefix = "trojan_plus_" local option_prefix = "trojan_plus_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -18,19 +18,19 @@ end
s.fields["type"]:value(type_name, "Trojan-Plus") s.fields["type"]:value(type_name, "Trojan-Plus")
o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
o = s:option(Value, option_name("port"), translate("Port")) o = s:option(Value, _n("port"), translate("Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(Value, option_name("password"), translate("Password")) o = s:option(Value, _n("password"), translate("Password"))
o.password = true o.password = true
o = s:option(ListValue, option_name("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required")) o = s:option(ListValue, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required"))
o:value("false") o:value("false")
o:value("true") o:value("true")
o = s:option(Flag, option_name("tls"), translate("TLS")) o = s:option(Flag, _n("tls"), translate("TLS"))
o.default = 0 o.default = 0
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value then if value then
@ -42,15 +42,15 @@ o.validate = function(self, value, t)
end end
end end
o = s:option(Flag, option_name("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped."))
o.default = "0" o.default = "0"
o:depends({ [option_name("tls")] = true }) o:depends({ [_n("tls")] = true })
o = s:option(Value, option_name("tls_serverName"), translate("Domain")) o = s:option(Value, _n("tls_serverName"), translate("Domain"))
o:depends({ [option_name("tls")] = true }) o:depends({ [_n("tls")] = true })
o = s:option(Flag, option_name("tls_sessionTicket"), translate("Session Ticket")) o = s:option(Flag, _n("tls_sessionTicket"), translate("Session Ticket"))
o.default = "0" o.default = "0"
o:depends({ [option_name("tls")] = true }) o:depends({ [_n("tls")] = true })
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -10,7 +10,7 @@ local type_name = "TUIC"
local option_prefix = "tuic_" local option_prefix = "tuic_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -18,16 +18,16 @@ end
s.fields["type"]:value(type_name, translate("TUIC")) s.fields["type"]:value(type_name, translate("TUIC"))
o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
o = s:option(Value, option_name("port"), translate("Port")) o = s:option(Value, _n("port"), translate("Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(Value, option_name("uuid"), translate("ID")) o = s:option(Value, _n("uuid"), translate("ID"))
o.password = true o.password = true
-- Tuic Password for remote server connect -- Tuic Password for remote server connect
o = s:option(Value, option_name("password"), translate("TUIC User Password For Connect Remote Server")) o = s:option(Value, _n("password"), translate("TUIC User Password For Connect Remote Server"))
o.password = true o.password = true
o.rmempty = true o.rmempty = true
o.default = "" o.default = ""
@ -35,32 +35,32 @@ o.rewrite_option = o.option
--[[ --[[
-- Tuic username for local socks connect -- Tuic username for local socks connect
o = s:option(Value, option_name("socks_username"), translate("TUIC UserName For Local Socks")) o = s:option(Value, _n("socks_username"), translate("TUIC UserName For Local Socks"))
o.rmempty = true o.rmempty = true
o.default = "" o.default = ""
o.rewrite_option = o.option o.rewrite_option = o.option
-- Tuic Password for local socks connect -- Tuic Password for local socks connect
o = s:option(Value, option_name("socks_password"), translate("TUIC Password For Local Socks")) o = s:option(Value, _n("socks_password"), translate("TUIC Password For Local Socks"))
o.password = true o.password = true
o.rmempty = true o.rmempty = true
o.default = "" o.default = ""
o.rewrite_option = o.option o.rewrite_option = o.option
--]] --]]
o = s:option(Value, option_name("ip"), translate("Set the TUIC proxy server ip address")) o = s:option(Value, _n("ip"), translate("Set the TUIC proxy server ip address"))
o.datatype = "ipaddr" o.datatype = "ipaddr"
o.rmempty = true o.rmempty = true
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(ListValue, option_name("udp_relay_mode"), translate("UDP relay mode")) o = s:option(ListValue, _n("udp_relay_mode"), translate("UDP relay mode"))
o:value("native", translate("native")) o:value("native", translate("native"))
o:value("quic", translate("QUIC")) o:value("quic", translate("QUIC"))
o.default = "native" o.default = "native"
o.rmempty = true o.rmempty = true
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(ListValue, option_name("congestion_control"), translate("Congestion control algorithm")) o = s:option(ListValue, _n("congestion_control"), translate("Congestion control algorithm"))
o:value("bbr", translate("BBR")) o:value("bbr", translate("BBR"))
o:value("cubic", translate("CUBIC")) o:value("cubic", translate("CUBIC"))
o:value("new_reno", translate("New Reno")) o:value("new_reno", translate("New Reno"))
@ -68,65 +68,65 @@ o.default = "cubic"
o.rmempty = true o.rmempty = true
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("heartbeat"), translate("Heartbeat interval(second)")) o = s:option(Value, _n("heartbeat"), translate("Heartbeat interval(second)"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = "3" o.default = "3"
o.rmempty = true o.rmempty = true
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("timeout"), translate("Timeout for establishing a connection to server(second)")) o = s:option(Value, _n("timeout"), translate("Timeout for establishing a connection to server(second)"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = "8" o.default = "8"
o.rmempty = true o.rmempty = true
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("gc_interval"), translate("Garbage collection interval(second)")) o = s:option(Value, _n("gc_interval"), translate("Garbage collection interval(second)"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = "3" o.default = "3"
o.rmempty = true o.rmempty = true
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("gc_lifetime"), translate("Garbage collection lifetime(second)")) o = s:option(Value, _n("gc_lifetime"), translate("Garbage collection lifetime(second)"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = "15" o.default = "15"
o.rmempty = true o.rmempty = true
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("send_window"), translate("TUIC send window")) o = s:option(Value, _n("send_window"), translate("TUIC send window"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = 20971520 o.default = 20971520
o.rmempty = true o.rmempty = true
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("receive_window"), translate("TUIC receive window")) o = s:option(Value, _n("receive_window"), translate("TUIC receive window"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = 10485760 o.default = 10485760
o.rmempty = true o.rmempty = true
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("max_package_size"), translate("TUIC Maximum packet size the socks5 server can receive from external, in bytes")) o = s:option(Value, _n("max_package_size"), translate("TUIC Maximum packet size the socks5 server can receive from external, in bytes"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = 1500 o.default = 1500
o.rmempty = true o.rmempty = true
o.rewrite_option = o.option o.rewrite_option = o.option
--Tuic settings for the local inbound socks5 server --Tuic settings for the local inbound socks5 server
o = s:option(Flag, option_name("dual_stack"), translate("Set if the listening socket should be dual-stack")) o = s:option(Flag, _n("dual_stack"), translate("Set if the listening socket should be dual-stack"))
o.default = 0 o.default = 0
o.rmempty = true o.rmempty = true
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Flag, option_name("disable_sni"), translate("Disable SNI")) o = s:option(Flag, _n("disable_sni"), translate("Disable SNI"))
o.default = 0 o.default = 0
o.rmempty = true o.rmempty = true
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Flag, option_name("zero_rtt_handshake"), translate("Enable 0-RTT QUIC handshake")) o = s:option(Flag, _n("zero_rtt_handshake"), translate("Enable 0-RTT QUIC handshake"))
o.default = 0 o.default = 0
o.rmempty = true o.rmempty = true
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(DynamicList, option_name("tls_alpn"), translate("TLS ALPN")) o = s:option(DynamicList, _n("tls_alpn"), translate("TLS ALPN"))
o.rmempty = true o.rmempty = true
o.rewrite_option = o.option o.rewrite_option = o.option

View File

@ -10,7 +10,7 @@ local type_name = "Hysteria2"
local option_prefix = "hysteria2_" local option_prefix = "hysteria2_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -18,31 +18,31 @@ end
s.fields["type"]:value(type_name, "Hysteria2") s.fields["type"]:value(type_name, "Hysteria2")
o = s:option(Value, option_name("port"), translate("Listen Port")) o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(Value, option_name("obfs"), translate("Obfs Password")) o = s:option(Value, _n("obfs"), translate("Obfs Password"))
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("auth_password"), translate("Auth Password")) o = s:option(Value, _n("auth_password"), translate("Auth Password"))
o.password = true o.password = true
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Flag, option_name("udp"), translate("UDP")) o = s:option(Flag, _n("udp"), translate("UDP"))
o.default = "1" o.default = "1"
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("up_mbps"), translate("Max upload Mbps")) o = s:option(Value, _n("up_mbps"), translate("Max upload Mbps"))
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Value, option_name("down_mbps"), translate("Max download Mbps")) o = s:option(Value, _n("down_mbps"), translate("Max download Mbps"))
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(Flag, option_name("ignoreClientBandwidth"), translate("ignoreClientBandwidth")) o = s:option(Flag, _n("ignoreClientBandwidth"), translate("ignoreClientBandwidth"))
o.default = "0" o.default = "0"
o.rewrite_option = o.option o.rewrite_option = o.option
o = s:option(FileUpload, option_name("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem") o = s:option(FileUpload, _n("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem" o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem"
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value and value ~= "" then if value and value ~= "" then
@ -55,7 +55,7 @@ o.validate = function(self, value, t)
return nil return nil
end end
o = s:option(FileUpload, option_name("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key") o = s:option(FileUpload, _n("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key" o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key"
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value and value ~= "" then if value and value ~= "" then
@ -68,7 +68,7 @@ o.validate = function(self, value, t)
return nil return nil
end end
o = s:option(Flag, option_name("log"), translate("Log")) o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1" o.default = "1"
o.rmempty = false o.rmempty = false

View File

@ -10,7 +10,7 @@ local type_name = "Xray"
local option_prefix = "xray_" local option_prefix = "xray_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -26,7 +26,7 @@ local header_type_list = {
s.fields["type"]:value(type_name, "Xray") s.fields["type"]:value(type_name, "Xray")
o = s:option(ListValue, option_name("protocol"), translate("Protocol")) o = s:option(ListValue, _n("protocol"), translate("Protocol"))
o:value("vmess", "Vmess") o:value("vmess", "Vmess")
o:value("vless", "VLESS") o:value("vless", "VLESS")
o:value("http", "HTTP") o:value("http", "HTTP")
@ -35,91 +35,91 @@ o:value("shadowsocks", "Shadowsocks")
o:value("trojan", "Trojan") o:value("trojan", "Trojan")
o:value("dokodemo-door", "dokodemo-door") o:value("dokodemo-door", "dokodemo-door")
o = s:option(Value, option_name("port"), translate("Listen Port")) o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(Flag, option_name("auth"), translate("Auth")) o = s:option(Flag, _n("auth"), translate("Auth"))
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value and value == "1" then if value and value == "1" then
local user_v = s.fields[option_name("username")] and s.fields[option_name("username")]:formvalue(t) or "" local user_v = s.fields[_n("username")] and s.fields[_n("username")]:formvalue(t) or ""
local pass_v = s.fields[option_name("password")] and s.fields[option_name("password")]:formvalue(t) or "" local pass_v = s.fields[_n("password")] and s.fields[_n("password")]:formvalue(t) or ""
if user_v == "" or pass_v == "" then if user_v == "" or pass_v == "" then
return nil, translate("Username and Password must be used together!") return nil, translate("Username and Password must be used together!")
end end
end end
return value return value
end end
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "http" }) o:depends({ [_n("protocol")] = "http" })
o = s:option(Value, option_name("username"), translate("Username")) o = s:option(Value, _n("username"), translate("Username"))
o:depends({ [option_name("auth")] = true }) o:depends({ [_n("auth")] = true })
o = s:option(Value, option_name("password"), translate("Password")) o = s:option(Value, _n("password"), translate("Password"))
o.password = true o.password = true
o:depends({ [option_name("auth")] = true }) o:depends({ [_n("auth")] = true })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(ListValue, option_name("d_protocol"), translate("Destination protocol")) o = s:option(ListValue, _n("d_protocol"), translate("Destination protocol"))
o:value("tcp", "TCP") o:value("tcp", "TCP")
o:value("udp", "UDP") o:value("udp", "UDP")
o:value("tcp,udp", "TCP,UDP") o:value("tcp,udp", "TCP,UDP")
o:depends({ [option_name("protocol")] = "dokodemo-door" }) o:depends({ [_n("protocol")] = "dokodemo-door" })
o = s:option(Value, option_name("d_address"), translate("Destination address")) o = s:option(Value, _n("d_address"), translate("Destination address"))
o:depends({ [option_name("protocol")] = "dokodemo-door" }) o:depends({ [_n("protocol")] = "dokodemo-door" })
o = s:option(Value, option_name("d_port"), translate("Destination port")) o = s:option(Value, _n("d_port"), translate("Destination port"))
o.datatype = "port" o.datatype = "port"
o:depends({ [option_name("protocol")] = "dokodemo-door" }) o:depends({ [_n("protocol")] = "dokodemo-door" })
o = s:option(Value, option_name("decryption"), translate("Encrypt Method")) o = s:option(Value, _n("decryption"), translate("Encrypt Method"))
o.default = "none" o.default = "none"
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o = s:option(ListValue, option_name("x_ss_method"), translate("Encrypt Method")) o = s:option(ListValue, _n("x_ss_method"), translate("Encrypt Method"))
o.rewrite_option = "method" o.rewrite_option = "method"
for a, t in ipairs(x_ss_method_list) do o:value(t) end for a, t in ipairs(x_ss_method_list) do o:value(t) end
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(Flag, option_name("iv_check"), translate("IV Check")) o = s:option(Flag, _n("iv_check"), translate("IV Check"))
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(ListValue, option_name("ss_network"), translate("Transport")) o = s:option(ListValue, _n("ss_network"), translate("Transport"))
o.default = "tcp,udp" o.default = "tcp,udp"
o:value("tcp", "TCP") o:value("tcp", "TCP")
o:value("udp", "UDP") o:value("udp", "UDP")
o:value("tcp,udp", "TCP,UDP") o:value("tcp,udp", "TCP,UDP")
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(Flag, option_name("udp_forward"), translate("UDP Forward")) o = s:option(Flag, _n("udp_forward"), translate("UDP Forward"))
o.default = "1" o.default = "1"
o.rmempty = false o.rmempty = false
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o = s:option(DynamicList, option_name("uuid"), translate("ID") .. "/" .. translate("Password")) o = s:option(DynamicList, _n("uuid"), translate("ID") .. "/" .. translate("Password"))
for i = 1, 3 do for i = 1, 3 do
o:value(api.gen_uuid(1)) o:value(api.gen_uuid(1))
end end
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
o = s:option(ListValue, option_name("flow"), translate("flow")) o = s:option(ListValue, _n("flow"), translate("flow"))
o.default = "" o.default = ""
o:value("", translate("Disable")) o:value("", translate("Disable"))
o:value("xtls-rprx-vision") o:value("xtls-rprx-vision")
o:depends({ [option_name("protocol")] = "vless", [option_name("tls")] = true, [option_name("transport")] = "raw" }) o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true, [_n("transport")] = "raw" })
o = s:option(Flag, option_name("tls"), translate("TLS")) o = s:option(Flag, _n("tls"), translate("TLS"))
o.default = 0 o.default = 0
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value then if value then
local reality = s.fields[option_name("reality")] and s.fields[option_name("reality")]:formvalue(t) or nil local reality = s.fields[_n("reality")] and s.fields[_n("reality")]:formvalue(t) or nil
if reality and reality == "1" then return value end if reality and reality == "1" then return value end
if value == "1" then if value == "1" then
local ca = s.fields[option_name("tls_certificateFile")] and s.fields[option_name("tls_certificateFile")]:formvalue(t) or "" local ca = s.fields[_n("tls_certificateFile")] and s.fields[_n("tls_certificateFile")]:formvalue(t) or ""
local key = s.fields[option_name("tls_keyFile")] and s.fields[option_name("tls_keyFile")]:formvalue(t) or "" local key = s.fields[_n("tls_keyFile")] and s.fields[_n("tls_keyFile")]:formvalue(t) or ""
if ca == "" or key == "" then if ca == "" or key == "" then
return nil, translate("Public key and Private key path can not be empty!") return nil, translate("Public key and Private key path can not be empty!")
end end
@ -127,32 +127,32 @@ o.validate = function(self, value, t)
return value return value
end end
end end
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "http" }) o:depends({ [_n("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
-- [[ REALITY部分 ]] -- -- [[ REALITY部分 ]] --
o = s:option(Flag, option_name("reality"), translate("REALITY")) o = s:option(Flag, _n("reality"), translate("REALITY"))
o.default = 0 o.default = 0
o:depends({ [option_name("tls")] = true }) o:depends({ [_n("tls")] = true })
o = s:option(Value, option_name("reality_private_key"), translate("Private Key")) o = s:option(Value, _n("reality_private_key"), translate("Private Key"))
o:depends({ [option_name("reality")] = true }) o:depends({ [_n("reality")] = true })
o = s:option(DynamicList, option_name("reality_shortId"), translate("Short Id")) o = s:option(DynamicList, _n("reality_shortId"), translate("Short Id"))
o:depends({ [option_name("reality")] = true }) o:depends({ [_n("reality")] = true })
o = s:option(Value, option_name("reality_dest"), translate("Dest")) o = s:option(Value, _n("reality_dest"), translate("Dest"))
o.default = "google.com:443" o.default = "google.com:443"
o:depends({ [option_name("reality")] = true }) o:depends({ [_n("reality")] = true })
o = s:option(Value, option_name("reality_serverNames"), translate("serverNames")) o = s:option(Value, _n("reality_serverNames"), translate("serverNames"))
o:depends({ [option_name("reality")] = true }) o:depends({ [_n("reality")] = true })
o = s:option(ListValue, option_name("alpn"), translate("alpn")) o = s:option(ListValue, _n("alpn"), translate("alpn"))
o.default = "h2,http/1.1" o.default = "h2,http/1.1"
o:value("h3") o:value("h3")
o:value("h2") o:value("h2")
@ -160,18 +160,18 @@ o:value("h3,h2")
o:value("http/1.1") o:value("http/1.1")
o:value("h2,http/1.1") o:value("h2,http/1.1")
o:value("h3,h2,http/1.1") o:value("h3,h2,http/1.1")
o:depends({ [option_name("tls")] = true }) o:depends({ [_n("tls")] = true })
-- o = s:option(Value, option_name("minversion"), translate("minversion")) -- o = s:option(Value, _n("minversion"), translate("minversion"))
-- o.default = "1.3" -- o.default = "1.3"
-- o:value("1.3") -- o:value("1.3")
--o:depends({ [option_name("tls")] = true }) --o:depends({ [_n("tls")] = true })
-- [[ TLS部分 ]] -- -- [[ TLS部分 ]] --
o = s:option(FileUpload, option_name("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem") o = s:option(FileUpload, _n("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem" o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem"
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false }) o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value and value ~= "" then if value and value ~= "" then
if not nixio.fs.access(value) then if not nixio.fs.access(value) then
@ -183,9 +183,9 @@ o.validate = function(self, value, t)
return nil return nil
end end
o = s:option(FileUpload, option_name("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key") o = s:option(FileUpload, _n("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key" o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key"
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false }) o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value and value ~= "" then if value and value ~= "" then
if not nixio.fs.access(value) then if not nixio.fs.access(value) then
@ -197,7 +197,7 @@ o.validate = function(self, value, t)
return nil return nil
end end
o = s:option(ListValue, option_name("transport"), translate("Transport")) o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("raw", "RAW") o:value("raw", "RAW")
o:value("mkcp", "mKCP") o:value("mkcp", "mKCP")
o:value("ws", "WebSocket") o:value("ws", "WebSocket")
@ -207,157 +207,157 @@ o:value("quic", "QUIC")
o:value("grpc", "gRPC") o:value("grpc", "gRPC")
o:value("httpupgrade", "HttpUpgrade") o:value("httpupgrade", "HttpUpgrade")
o:value("xhttp", "XHTTP") o:value("xhttp", "XHTTP")
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
-- [[ WebSocket部分 ]]-- -- [[ WebSocket部分 ]]--
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host")) o = s:option(Value, _n("ws_host"), translate("WebSocket Host"))
o:depends({ [option_name("transport")] = "ws" }) o:depends({ [_n("transport")] = "ws" })
o = s:option(Value, option_name("ws_path"), translate("WebSocket Path")) o = s:option(Value, _n("ws_path"), translate("WebSocket Path"))
o:depends({ [option_name("transport")] = "ws" }) o:depends({ [_n("transport")] = "ws" })
-- [[ HttpUpgrade部分 ]]-- -- [[ HttpUpgrade部分 ]]--
o = s:option(Value, option_name("httpupgrade_host"), translate("HttpUpgrade Host")) o = s:option(Value, _n("httpupgrade_host"), translate("HttpUpgrade Host"))
o:depends({ [option_name("transport")] = "httpupgrade" }) o:depends({ [_n("transport")] = "httpupgrade" })
o = s:option(Value, option_name("httpupgrade_path"), translate("HttpUpgrade Path")) o = s:option(Value, _n("httpupgrade_path"), translate("HttpUpgrade Path"))
o.placeholder = "/" o.placeholder = "/"
o:depends({ [option_name("transport")] = "httpupgrade" }) o:depends({ [_n("transport")] = "httpupgrade" })
-- [[ SplitHTTP部分 ]]-- -- [[ SplitHTTP部分 ]]--
o = s:option(Value, option_name("xhttp_host"), translate("XHTTP Host")) o = s:option(Value, _n("xhttp_host"), translate("XHTTP Host"))
o:depends({ [option_name("transport")] = "xhttp" }) o:depends({ [_n("transport")] = "xhttp" })
o = s:option(Value, option_name("xhttp_path"), translate("XHTTP Path")) o = s:option(Value, _n("xhttp_path"), translate("XHTTP Path"))
o.placeholder = "/" o.placeholder = "/"
o:depends({ [option_name("transport")] = "xhttp" }) o:depends({ [_n("transport")] = "xhttp" })
o = s:option(Value, option_name("xhttp_maxuploadsize"), translate("maxUploadSize")) o = s:option(Value, _n("xhttp_maxuploadsize"), translate("maxUploadSize"))
o.default = "1000000" o.default = "1000000"
o:depends({ [option_name("transport")] = "xhttp" }) o:depends({ [_n("transport")] = "xhttp" })
o = s:option(Value, option_name("xhttp_maxconcurrentuploads"), translate("maxConcurrentUploads")) o = s:option(Value, _n("xhttp_maxconcurrentuploads"), translate("maxConcurrentUploads"))
o.default = "10" o.default = "10"
o:depends({ [option_name("transport")] = "xhttp" }) o:depends({ [_n("transport")] = "xhttp" })
-- [[ HTTP/2部分 ]]-- -- [[ HTTP/2部分 ]]--
o = s:option(Value, option_name("h2_host"), translate("HTTP/2 Host")) o = s:option(Value, _n("h2_host"), translate("HTTP/2 Host"))
o:depends({ [option_name("transport")] = "h2" }) o:depends({ [_n("transport")] = "h2" })
o = s:option(Value, option_name("h2_path"), translate("HTTP/2 Path")) o = s:option(Value, _n("h2_path"), translate("HTTP/2 Path"))
o:depends({ [option_name("transport")] = "h2" }) o:depends({ [_n("transport")] = "h2" })
-- [[ TCP部分 ]]-- -- [[ TCP部分 ]]--
-- TCP伪装 -- TCP伪装
o = s:option(ListValue, option_name("tcp_guise"), translate("Camouflage Type")) o = s:option(ListValue, _n("tcp_guise"), translate("Camouflage Type"))
o:value("none", "none") o:value("none", "none")
o:value("http", "http") o:value("http", "http")
o:depends({ [option_name("transport")] = "raw" }) o:depends({ [_n("transport")] = "raw" })
-- HTTP域名 -- HTTP域名
o = s:option(DynamicList, option_name("tcp_guise_http_host"), translate("HTTP Host")) o = s:option(DynamicList, _n("tcp_guise_http_host"), translate("HTTP Host"))
o:depends({ [option_name("tcp_guise")] = "http" }) o:depends({ [_n("tcp_guise")] = "http" })
-- HTTP路径 -- HTTP路径
o = s:option(DynamicList, option_name("tcp_guise_http_path"), translate("HTTP Path")) o = s:option(DynamicList, _n("tcp_guise_http_path"), translate("HTTP Path"))
o:depends({ [option_name("tcp_guise")] = "http" }) o:depends({ [_n("tcp_guise")] = "http" })
-- [[ mKCP部分 ]]-- -- [[ mKCP部分 ]]--
o = s:option(ListValue, option_name("mkcp_guise"), translate("Camouflage Type"), translate('<br />none: default, no masquerade, data sent is packets with no characteristics.<br />srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).<br />utp: packets disguised as uTP will be recognized as bittorrent downloaded data.<br />wechat-video: packets disguised as WeChat video calls.<br />dtls: disguised as DTLS 1.2 packet.<br />wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)')) o = s:option(ListValue, _n("mkcp_guise"), translate("Camouflage Type"), translate('<br />none: default, no masquerade, data sent is packets with no characteristics.<br />srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).<br />utp: packets disguised as uTP will be recognized as bittorrent downloaded data.<br />wechat-video: packets disguised as WeChat video calls.<br />dtls: disguised as DTLS 1.2 packet.<br />wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)'))
for a, t in ipairs(header_type_list) do o:value(t) end for a, t in ipairs(header_type_list) do o:value(t) end
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_mtu"), translate("KCP MTU")) o = s:option(Value, _n("mkcp_mtu"), translate("KCP MTU"))
o.default = "1350" o.default = "1350"
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_tti"), translate("KCP TTI")) o = s:option(Value, _n("mkcp_tti"), translate("KCP TTI"))
o.default = "20" o.default = "20"
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_uplinkCapacity"), translate("KCP uplinkCapacity")) o = s:option(Value, _n("mkcp_uplinkCapacity"), translate("KCP uplinkCapacity"))
o.default = "5" o.default = "5"
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_downlinkCapacity"), translate("KCP downlinkCapacity")) o = s:option(Value, _n("mkcp_downlinkCapacity"), translate("KCP downlinkCapacity"))
o.default = "20" o.default = "20"
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Flag, option_name("mkcp_congestion"), translate("KCP Congestion")) o = s:option(Flag, _n("mkcp_congestion"), translate("KCP Congestion"))
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_readBufferSize"), translate("KCP readBufferSize")) o = s:option(Value, _n("mkcp_readBufferSize"), translate("KCP readBufferSize"))
o.default = "1" o.default = "1"
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_writeBufferSize"), translate("KCP writeBufferSize")) o = s:option(Value, _n("mkcp_writeBufferSize"), translate("KCP writeBufferSize"))
o.default = "1" o.default = "1"
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_seed"), translate("KCP Seed")) o = s:option(Value, _n("mkcp_seed"), translate("KCP Seed"))
o:depends({ [option_name("transport")] = "mkcp" }) o:depends({ [_n("transport")] = "mkcp" })
-- [[ DomainSocket部分 ]]-- -- [[ DomainSocket部分 ]]--
o = s:option(Value, option_name("ds_path"), "Path", translate("A legal file path. This file must not exist before running.")) o = s:option(Value, _n("ds_path"), "Path", translate("A legal file path. This file must not exist before running."))
o:depends({ [option_name("transport")] = "ds" }) o:depends({ [_n("transport")] = "ds" })
-- [[ QUIC部分 ]]-- -- [[ QUIC部分 ]]--
o = s:option(ListValue, option_name("quic_security"), translate("Encrypt Method")) o = s:option(ListValue, _n("quic_security"), translate("Encrypt Method"))
o:value("none") o:value("none")
o:value("aes-128-gcm") o:value("aes-128-gcm")
o:value("chacha20-poly1305") o:value("chacha20-poly1305")
o:depends({ [option_name("transport")] = "quic" }) o:depends({ [_n("transport")] = "quic" })
o = s:option(Value, option_name("quic_key"), translate("Encrypt Method") .. translate("Key")) o = s:option(Value, _n("quic_key"), translate("Encrypt Method") .. translate("Key"))
o:depends({ [option_name("transport")] = "quic" }) o:depends({ [_n("transport")] = "quic" })
o = s:option(ListValue, option_name("quic_guise"), translate("Camouflage Type")) o = s:option(ListValue, _n("quic_guise"), translate("Camouflage Type"))
for a, t in ipairs(header_type_list) do o:value(t) end for a, t in ipairs(header_type_list) do o:value(t) end
o:depends({ [option_name("transport")] = "quic" }) o:depends({ [_n("transport")] = "quic" })
-- [[ gRPC部分 ]]-- -- [[ gRPC部分 ]]--
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName") o = s:option(Value, _n("grpc_serviceName"), "ServiceName")
o:depends({ [option_name("transport")] = "grpc" }) o:depends({ [_n("transport")] = "grpc" })
o = s:option(Flag, option_name("acceptProxyProtocol"), translate("acceptProxyProtocol"), translate("Whether to receive PROXY protocol, when this node want to be fallback or forwarded by proxy, it must be enable, otherwise it cannot be used.")) o = s:option(Flag, _n("acceptProxyProtocol"), translate("acceptProxyProtocol"), translate("Whether to receive PROXY protocol, when this node want to be fallback or forwarded by proxy, it must be enable, otherwise it cannot be used."))
o.default = "0" o.default = "0"
-- [[ Fallback部分 ]]-- -- [[ Fallback部分 ]]--
o = s:option(Flag, option_name("fallback"), translate("Fallback")) o = s:option(Flag, _n("fallback"), translate("Fallback"))
o:depends({ [option_name("protocol")] = "vless", [option_name("transport")] = "raw" }) o:depends({ [_n("protocol")] = "vless", [_n("transport")] = "raw" })
o:depends({ [option_name("protocol")] = "trojan", [option_name("transport")] = "raw" }) o:depends({ [_n("protocol")] = "trojan", [_n("transport")] = "raw" })
--[[ --[[
o = s:option(Value, option_name("fallback_alpn"), "Fallback alpn") o = s:option(Value, _n("fallback_alpn"), "Fallback alpn")
o:depends({ [option_name("fallback")] = true }) o:depends({ [_n("fallback")] = true })
o = s:option(Value, option_name("fallback_path"), "Fallback path") o = s:option(Value, _n("fallback_path"), "Fallback path")
o:depends({ [option_name("fallback")] = true }) o:depends({ [_n("fallback")] = true })
o = s:option(Value, option_name("fallback_dest"), "Fallback dest") o = s:option(Value, _n("fallback_dest"), "Fallback dest")
o:depends({ [option_name("fallback")] = true }) o:depends({ [_n("fallback")] = true })
o = s:option(Value, option_name("fallback_xver"), "Fallback xver") o = s:option(Value, _n("fallback_xver"), "Fallback xver")
o.default = 0 o.default = 0
o:depends({ [option_name("fallback")] = true }) o:depends({ [_n("fallback")] = true })
]]-- ]]--
o = s:option(DynamicList, option_name("fallback_list"), "Fallback", translate("dest,path")) o = s:option(DynamicList, _n("fallback_list"), "Fallback", translate("dest,path"))
o:depends({ [option_name("fallback")] = true }) o:depends({ [_n("fallback")] = true })
o = s:option(Flag, option_name("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) o = s:option(Flag, _n("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
o.default = "0" o.default = "0"
o = s:option(Flag, option_name("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!")) o = s:option(Flag, _n("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!"))
o.default = "0" o.default = "0"
local nodes_table = {} local nodes_table = {}
@ -370,46 +370,45 @@ for k, e in ipairs(api.get_valid_nodes()) do
end end
end end
o = s:option(ListValue, option_name("outbound_node"), translate("outbound node")) o = s:option(ListValue, _n("outbound_node"), translate("outbound node"))
o:value("nil", translate("Close")) o:value("", translate("Close"))
o:value("_socks", translate("Custom Socks")) o:value("_socks", translate("Custom Socks"))
o:value("_http", translate("Custom HTTP")) o:value("_http", translate("Custom HTTP"))
o:value("_iface", translate("Custom Interface")) o:value("_iface", translate("Custom Interface"))
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
o.default = "nil"
o = s:option(Value, option_name("outbound_node_address"), translate("Address (Support Domain Name)")) o = s:option(Value, _n("outbound_node_address"), translate("Address (Support Domain Name)"))
o:depends({ [option_name("outbound_node")] = "_socks"}) o:depends({ [_n("outbound_node")] = "_socks"})
o:depends({ [option_name("outbound_node")] = "_http"}) o:depends({ [_n("outbound_node")] = "_http"})
o = s:option(Value, option_name("outbound_node_port"), translate("Port")) o = s:option(Value, _n("outbound_node_port"), translate("Port"))
o.datatype = "port" o.datatype = "port"
o:depends({ [option_name("outbound_node")] = "_socks"}) o:depends({ [_n("outbound_node")] = "_socks"})
o:depends({ [option_name("outbound_node")] = "_http"}) o:depends({ [_n("outbound_node")] = "_http"})
o = s:option(Value, option_name("outbound_node_username"), translate("Username")) o = s:option(Value, _n("outbound_node_username"), translate("Username"))
o:depends({ [option_name("outbound_node")] = "_socks"}) o:depends({ [_n("outbound_node")] = "_socks"})
o:depends({ [option_name("outbound_node")] = "_http"}) o:depends({ [_n("outbound_node")] = "_http"})
o = s:option(Value, option_name("outbound_node_password"), translate("Password")) o = s:option(Value, _n("outbound_node_password"), translate("Password"))
o.password = true o.password = true
o:depends({ [option_name("outbound_node")] = "_socks"}) o:depends({ [_n("outbound_node")] = "_socks"})
o:depends({ [option_name("outbound_node")] = "_http"}) o:depends({ [_n("outbound_node")] = "_http"})
o = s:option(Value, option_name("outbound_node_iface"), translate("Interface")) o = s:option(Value, _n("outbound_node_iface"), translate("Interface"))
o.default = "eth1" o.default = "eth1"
o:depends({ [option_name("outbound_node")] = "_iface"}) o:depends({ [_n("outbound_node")] = "_iface"})
o = s:option(Flag, option_name("log"), translate("Log")) o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1" o.default = "1"
o.rmempty = false o.rmempty = false
o = s:option(ListValue, option_name("loglevel"), translate("Log Level")) o = s:option(ListValue, _n("loglevel"), translate("Log Level"))
o.default = "warning" o.default = "warning"
o:value("debug") o:value("debug")
o:value("info") o:value("info")
o:value("warning") o:value("warning")
o:value("error") o:value("error")
o:depends({ [option_name("log")] = true }) o:depends({ [_n("log")] = true })
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -14,7 +14,7 @@ local type_name = "sing-box"
local option_prefix = "singbox_" local option_prefix = "singbox_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -27,7 +27,7 @@ local ss_method_list = {
s.fields["type"]:value(type_name, "Sing-Box") s.fields["type"]:value(type_name, "Sing-Box")
o = s:option(ListValue, option_name("protocol"), translate("Protocol")) o = s:option(ListValue, _n("protocol"), translate("Protocol"))
o:value("mixed", "Mixed") o:value("mixed", "Mixed")
o:value("socks", "Socks") o:value("socks", "Socks")
o:value("http", "HTTP") o:value("http", "HTTP")
@ -47,166 +47,166 @@ if singbox_tags:find("with_quic") then
end end
o:value("direct", "Direct") o:value("direct", "Direct")
o = s:option(Value, option_name("port"), translate("Listen Port")) o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(Flag, option_name("auth"), translate("Auth")) o = s:option(Flag, _n("auth"), translate("Auth"))
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value and value == "1" then if value and value == "1" then
local user_v = s.fields[option_name("username")] and s.fields[option_name("username")]:formvalue(t) or "" local user_v = s.fields[_n("username")] and s.fields[_n("username")]:formvalue(t) or ""
local pass_v = s.fields[option_name("password")] and s.fields[option_name("password")]:formvalue(t) or "" local pass_v = s.fields[_n("password")] and s.fields[_n("password")]:formvalue(t) or ""
if user_v == "" or pass_v == "" then if user_v == "" or pass_v == "" then
return nil, translate("Username and Password must be used together!") return nil, translate("Username and Password must be used together!")
end end
end end
return value return value
end end
o:depends({ [option_name("protocol")] = "mixed" }) o:depends({ [_n("protocol")] = "mixed" })
o:depends({ [option_name("protocol")] = "socks" }) o:depends({ [_n("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "http" }) o:depends({ [_n("protocol")] = "http" })
o = s:option(Value, option_name("username"), translate("Username")) o = s:option(Value, _n("username"), translate("Username"))
o:depends({ [option_name("auth")] = true }) o:depends({ [_n("auth")] = true })
o:depends({ [option_name("protocol")] = "naive" }) o:depends({ [_n("protocol")] = "naive" })
o = s:option(Value, option_name("password"), translate("Password")) o = s:option(Value, _n("password"), translate("Password"))
o.password = true o.password = true
o:depends({ [option_name("auth")] = true }) o:depends({ [_n("auth")] = true })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "naive" }) o:depends({ [_n("protocol")] = "naive" })
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
if singbox_tags:find("with_quic") then if singbox_tags:find("with_quic") then
o = s:option(Value, option_name("hysteria_up_mbps"), translate("Max upload Mbps")) o = s:option(Value, _n("hysteria_up_mbps"), translate("Max upload Mbps"))
o.default = "100" o.default = "100"
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_down_mbps"), translate("Max download Mbps")) o = s:option(Value, _n("hysteria_down_mbps"), translate("Max download Mbps"))
o.default = "100" o.default = "100"
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_obfs"), translate("Obfs Password")) o = s:option(Value, _n("hysteria_obfs"), translate("Obfs Password"))
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(ListValue, option_name("hysteria_auth_type"), translate("Auth Type")) o = s:option(ListValue, _n("hysteria_auth_type"), translate("Auth Type"))
o:value("disable", translate("Disable")) o:value("disable", translate("Disable"))
o:value("string", translate("STRING")) o:value("string", translate("STRING"))
o:value("base64", translate("BASE64")) o:value("base64", translate("BASE64"))
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_auth_password"), translate("Auth Password")) o = s:option(Value, _n("hysteria_auth_password"), translate("Auth Password"))
o.password = true o.password = true
o:depends({ [option_name("protocol")] = "hysteria", [option_name("hysteria_auth_type")] = "string"}) o:depends({ [_n("protocol")] = "hysteria", [_n("hysteria_auth_type")] = "string"})
o:depends({ [option_name("protocol")] = "hysteria", [option_name("hysteria_auth_type")] = "base64"}) o:depends({ [_n("protocol")] = "hysteria", [_n("hysteria_auth_type")] = "base64"})
o = s:option(Value, option_name("hysteria_recv_window_conn"), translate("QUIC stream receive window")) o = s:option(Value, _n("hysteria_recv_window_conn"), translate("QUIC stream receive window"))
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_recv_window_client"), translate("QUIC connection receive window")) o = s:option(Value, _n("hysteria_recv_window_client"), translate("QUIC connection receive window"))
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_max_conn_client"), translate("QUIC concurrent bidirectional streams")) o = s:option(Value, _n("hysteria_max_conn_client"), translate("QUIC concurrent bidirectional streams"))
o.default = "1024" o.default = "1024"
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Flag, option_name("hysteria_disable_mtu_discovery"), translate("Disable MTU detection")) o = s:option(Flag, _n("hysteria_disable_mtu_discovery"), translate("Disable MTU detection"))
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_alpn"), translate("QUIC TLS ALPN")) o = s:option(Value, _n("hysteria_alpn"), translate("QUIC TLS ALPN"))
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
end end
if singbox_tags:find("with_quic") then if singbox_tags:find("with_quic") then
o = s:option(ListValue, option_name("tuic_congestion_control"), translate("Congestion control algorithm")) o = s:option(ListValue, _n("tuic_congestion_control"), translate("Congestion control algorithm"))
o.default = "cubic" o.default = "cubic"
o:value("bbr", translate("BBR")) o:value("bbr", translate("BBR"))
o:value("cubic", translate("CUBIC")) o:value("cubic", translate("CUBIC"))
o:value("new_reno", translate("New Reno")) o:value("new_reno", translate("New Reno"))
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o = s:option(Flag, option_name("tuic_zero_rtt_handshake"), translate("Enable 0-RTT QUIC handshake")) o = s:option(Flag, _n("tuic_zero_rtt_handshake"), translate("Enable 0-RTT QUIC handshake"))
o.default = 0 o.default = 0
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o = s:option(Value, option_name("tuic_heartbeat"), translate("Heartbeat interval(second)")) o = s:option(Value, _n("tuic_heartbeat"), translate("Heartbeat interval(second)"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = "3" o.default = "3"
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o = s:option(Value, option_name("tuic_alpn"), translate("QUIC TLS ALPN")) o = s:option(Value, _n("tuic_alpn"), translate("QUIC TLS ALPN"))
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
end end
if singbox_tags:find("with_quic") then if singbox_tags:find("with_quic") then
o = s:option(Flag, option_name("hysteria2_ignore_client_bandwidth"), translate("Commands the client to use the BBR flow control algorithm")) o = s:option(Flag, _n("hysteria2_ignore_client_bandwidth"), translate("Commands the client to use the BBR flow control algorithm"))
o.default = 0 o.default = 0
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, option_name("hysteria2_up_mbps"), translate("Max upload Mbps")) o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
o:depends({ [option_name("protocol")] = "hysteria2", [option_name("hysteria2_ignore_client_bandwidth")] = false }) o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_ignore_client_bandwidth")] = false })
o = s:option(Value, option_name("hysteria2_down_mbps"), translate("Max download Mbps")) o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps"))
o:depends({ [option_name("protocol")] = "hysteria2", [option_name("hysteria2_ignore_client_bandwidth")] = false }) o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_ignore_client_bandwidth")] = false })
o = s:option(ListValue, option_name("hysteria2_obfs_type"), translate("Obfs Type")) o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type"))
o:value("", translate("Disable")) o:value("", translate("Disable"))
o:value("salamander") o:value("salamander")
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, option_name("hysteria2_obfs_password"), translate("Obfs Password")) o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, option_name("hysteria2_auth_password"), translate("Auth Password")) o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password"))
o.password = true o.password = true
o:depends({ [option_name("protocol")] = "hysteria2"}) o:depends({ [_n("protocol")] = "hysteria2"})
end end
o = s:option(ListValue, option_name("d_protocol"), translate("Destination protocol")) o = s:option(ListValue, _n("d_protocol"), translate("Destination protocol"))
o:value("tcp", "TCP") o:value("tcp", "TCP")
o:value("udp", "UDP") o:value("udp", "UDP")
o:value("tcp,udp", "TCP,UDP") o:value("tcp,udp", "TCP,UDP")
o:depends({ [option_name("protocol")] = "direct" }) o:depends({ [_n("protocol")] = "direct" })
o = s:option(Value, option_name("d_address"), translate("Destination address")) o = s:option(Value, _n("d_address"), translate("Destination address"))
o:depends({ [option_name("protocol")] = "direct" }) o:depends({ [_n("protocol")] = "direct" })
o = s:option(Value, option_name("d_port"), translate("Destination port")) o = s:option(Value, _n("d_port"), translate("Destination port"))
o.datatype = "port" o.datatype = "port"
o:depends({ [option_name("protocol")] = "direct" }) o:depends({ [_n("protocol")] = "direct" })
o = s:option(Value, option_name("decryption"), translate("Encrypt Method")) o = s:option(Value, _n("decryption"), translate("Encrypt Method"))
o.default = "none" o.default = "none"
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o = s:option(ListValue, option_name("ss_method"), translate("Encrypt Method")) o = s:option(ListValue, _n("ss_method"), translate("Encrypt Method"))
o.rewrite_option = "method" o.rewrite_option = "method"
for a, t in ipairs(ss_method_list) do o:value(t) end for a, t in ipairs(ss_method_list) do o:value(t) end
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(DynamicList, option_name("uuid"), translate("ID") .. "/" .. translate("Password")) o = s:option(DynamicList, _n("uuid"), translate("ID") .. "/" .. translate("Password"))
for i = 1, 3 do for i = 1, 3 do
o:value(api.gen_uuid(1)) o:value(api.gen_uuid(1))
end end
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o = s:option(ListValue, option_name("flow"), translate("flow")) o = s:option(ListValue, _n("flow"), translate("flow"))
o.default = "" o.default = ""
o:value("", translate("Disable")) o:value("", translate("Disable"))
o:value("xtls-rprx-vision") o:value("xtls-rprx-vision")
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o = s:option(Flag, option_name("tls"), translate("TLS")) o = s:option(Flag, _n("tls"), translate("TLS"))
o.default = 0 o.default = 0
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value then if value then
local reality = s.fields[option_name("reality")] and s.fields[option_name("reality")]:formvalue(t) or nil local reality = s.fields[_n("reality")] and s.fields[_n("reality")]:formvalue(t) or nil
if reality and reality == "1" then return value end if reality and reality == "1" then return value end
if value == "1" then if value == "1" then
local ca = s.fields[option_name("tls_certificateFile")] and s.fields[option_name("tls_certificateFile")]:formvalue(t) or "" local ca = s.fields[_n("tls_certificateFile")] and s.fields[_n("tls_certificateFile")]:formvalue(t) or ""
local key = s.fields[option_name("tls_keyFile")] and s.fields[option_name("tls_keyFile")]:formvalue(t) or "" local key = s.fields[_n("tls_keyFile")] and s.fields[_n("tls_keyFile")]:formvalue(t) or ""
if ca == "" or key == "" then if ca == "" or key == "" then
return nil, translate("Public key and Private key path can not be empty!") return nil, translate("Public key and Private key path can not be empty!")
end end
@ -214,45 +214,45 @@ o.validate = function(self, value, t)
return value return value
end end
end end
o:depends({ [option_name("protocol")] = "http" }) o:depends({ [_n("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
if singbox_tags:find("with_reality_server") then if singbox_tags:find("with_reality_server") then
-- [[ REALITY部分 ]] -- -- [[ REALITY部分 ]] --
o = s:option(Flag, option_name("reality"), translate("REALITY")) o = s:option(Flag, _n("reality"), translate("REALITY"))
o.default = 0 o.default = 0
o:depends({ [option_name("protocol")] = "http", [option_name("tls")] = true }) o:depends({ [_n("protocol")] = "http", [_n("tls")] = true })
o:depends({ [option_name("protocol")] = "vmess", [option_name("tls")] = true }) o:depends({ [_n("protocol")] = "vmess", [_n("tls")] = true })
o:depends({ [option_name("protocol")] = "vless", [option_name("tls")] = true }) o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true })
o:depends({ [option_name("protocol")] = "trojan", [option_name("tls")] = true }) o:depends({ [_n("protocol")] = "trojan", [_n("tls")] = true })
o = s:option(Value, option_name("reality_private_key"), translate("Private Key")) o = s:option(Value, _n("reality_private_key"), translate("Private Key"))
o:depends({ [option_name("reality")] = true }) o:depends({ [_n("reality")] = true })
o = s:option(Value, option_name("reality_shortId"), translate("Short Id")) o = s:option(Value, _n("reality_shortId"), translate("Short Id"))
o:depends({ [option_name("reality")] = true }) o:depends({ [_n("reality")] = true })
o = s:option(Value, option_name("reality_handshake_server"), translate("Handshake Server")) o = s:option(Value, _n("reality_handshake_server"), translate("Handshake Server"))
o.default = "google.com" o.default = "google.com"
o:depends({ [option_name("reality")] = true }) o:depends({ [_n("reality")] = true })
o = s:option(Value, option_name("reality_handshake_server_port"), translate("Handshake Server Port")) o = s:option(Value, _n("reality_handshake_server_port"), translate("Handshake Server Port"))
o.datatype = "port" o.datatype = "port"
o.default = "443" o.default = "443"
o:depends({ [option_name("reality")] = true }) o:depends({ [_n("reality")] = true })
end end
-- [[ TLS部分 ]] -- -- [[ TLS部分 ]] --
o = s:option(FileUpload, option_name("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem") o = s:option(FileUpload, _n("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem" o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem"
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false }) o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o:depends({ [option_name("protocol")] = "naive" }) o:depends({ [_n("protocol")] = "naive" })
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value and value ~= "" then if value and value ~= "" then
if not nixio.fs.access(value) then if not nixio.fs.access(value) then
@ -264,13 +264,13 @@ o.validate = function(self, value, t)
return nil return nil
end end
o = s:option(FileUpload, option_name("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key") o = s:option(FileUpload, _n("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key" o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key"
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false }) o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o:depends({ [option_name("protocol")] = "naive" }) o:depends({ [_n("protocol")] = "naive" })
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value and value ~= "" then if value and value ~= "" then
if not nixio.fs.access(value) then if not nixio.fs.access(value) then
@ -283,19 +283,19 @@ o.validate = function(self, value, t)
end end
if singbox_tags:find("with_ech") then if singbox_tags:find("with_ech") then
o = s:option(Flag, option_name("ech"), translate("ECH")) o = s:option(Flag, _n("ech"), translate("ECH"))
o.default = "0" o.default = "0"
o:depends({ [option_name("tls")] = true, [option_name("flow")] = "", [option_name("reality")] = false }) o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
o:depends({ [option_name("protocol")] = "naive" }) o:depends({ [_n("protocol")] = "naive" })
o:depends({ [option_name("protocol")] = "hysteria" }) o:depends({ [_n("protocol")] = "hysteria" })
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(TextValue, option_name("ech_key"), translate("ECH Key")) o = s:option(TextValue, _n("ech_key"), translate("ECH Key"))
o.default = "" o.default = ""
o.rows = 5 o.rows = 5
o.wrap = "off" o.wrap = "off"
o:depends({ [option_name("ech")] = true }) o:depends({ [_n("ech")] = true })
o.validate = function(self, value) o.validate = function(self, value)
value = value:gsub("^%s+", ""):gsub("%s+$","\n"):gsub("\r\n","\n"):gsub("[ \t]*\n[ \t]*", "\n") value = value:gsub("^%s+", ""):gsub("%s+$","\n"):gsub("\r\n","\n"):gsub("[ \t]*\n[ \t]*", "\n")
value = value:gsub("^%s*\n", "") value = value:gsub("^%s*\n", "")
@ -305,80 +305,80 @@ if singbox_tags:find("with_ech") then
return value return value
end end
o = s:option(Flag, option_name("pq_signature_schemes_enabled"), translate("PQ signature schemes")) o = s:option(Flag, _n("pq_signature_schemes_enabled"), translate("PQ signature schemes"))
o.default = "0" o.default = "0"
o:depends({ [option_name("ech")] = true }) o:depends({ [_n("ech")] = true })
o = s:option(Flag, option_name("dynamic_record_sizing_disabled"), translate("Disable adaptive sizing of TLS records")) o = s:option(Flag, _n("dynamic_record_sizing_disabled"), translate("Disable adaptive sizing of TLS records"))
o.default = "0" o.default = "0"
o:depends({ [option_name("ech")] = true }) o:depends({ [_n("ech")] = true })
end end
o = s:option(ListValue, option_name("transport"), translate("Transport")) o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("tcp", "TCP") o:value("tcp", "TCP")
o:value("http", "HTTP") o:value("http", "HTTP")
o:value("ws", "WebSocket") o:value("ws", "WebSocket")
o:value("httpupgrade", "HTTPUpgrade") o:value("httpupgrade", "HTTPUpgrade")
o:value("quic", "QUIC") o:value("quic", "QUIC")
o:value("grpc", "gRPC") o:value("grpc", "gRPC")
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
-- [[ HTTP部分 ]]-- -- [[ HTTP部分 ]]--
o = s:option(Value, option_name("http_host"), translate("HTTP Host")) o = s:option(Value, _n("http_host"), translate("HTTP Host"))
o:depends({ [option_name("transport")] = "http" }) o:depends({ [_n("transport")] = "http" })
o = s:option(Value, option_name("http_path"), translate("HTTP Path")) o = s:option(Value, _n("http_path"), translate("HTTP Path"))
o:depends({ [option_name("transport")] = "http" }) o:depends({ [_n("transport")] = "http" })
-- [[ WebSocket部分 ]]-- -- [[ WebSocket部分 ]]--
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host")) o = s:option(Value, _n("ws_host"), translate("WebSocket Host"))
o:depends({ [option_name("transport")] = "ws" }) o:depends({ [_n("transport")] = "ws" })
o = s:option(Value, option_name("ws_path"), translate("WebSocket Path")) o = s:option(Value, _n("ws_path"), translate("WebSocket Path"))
o:depends({ [option_name("transport")] = "ws" }) o:depends({ [_n("transport")] = "ws" })
-- [[ HTTPUpgrade部分 ]]-- -- [[ HTTPUpgrade部分 ]]--
o = s:option(Value, option_name("httpupgrade_host"), translate("HTTPUpgrade Host")) o = s:option(Value, _n("httpupgrade_host"), translate("HTTPUpgrade Host"))
o:depends({ [option_name("transport")] = "httpupgrade" }) o:depends({ [_n("transport")] = "httpupgrade" })
o = s:option(Value, option_name("httpupgrade_path"), translate("HTTPUpgrade Path")) o = s:option(Value, _n("httpupgrade_path"), translate("HTTPUpgrade Path"))
o:depends({ [option_name("transport")] = "httpupgrade" }) o:depends({ [_n("transport")] = "httpupgrade" })
-- [[ gRPC部分 ]]-- -- [[ gRPC部分 ]]--
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName") o = s:option(Value, _n("grpc_serviceName"), "ServiceName")
o:depends({ [option_name("transport")] = "grpc" }) o:depends({ [_n("transport")] = "grpc" })
-- [[ Mux ]]-- -- [[ Mux ]]--
o = s:option(Flag, option_name("mux"), translate("Mux")) o = s:option(Flag, _n("mux"), translate("Mux"))
o.rmempty = false o.rmempty = false
o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless", [option_name("flow")] = "" }) o:depends({ [_n("protocol")] = "vless", [_n("flow")] = "" })
o:depends({ [option_name("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "trojan" })
-- [[ TCP Brutal ]]-- -- [[ TCP Brutal ]]--
o = s:option(Flag, option_name("tcpbrutal"), translate("TCP Brutal")) o = s:option(Flag, _n("tcpbrutal"), translate("TCP Brutal"))
o.default = 0 o.default = 0
o:depends({ [option_name("mux")] = true }) o:depends({ [_n("mux")] = true })
o = s:option(Value, option_name("tcpbrutal_up_mbps"), translate("Max upload Mbps")) o = s:option(Value, _n("tcpbrutal_up_mbps"), translate("Max upload Mbps"))
o.default = "10" o.default = "10"
o:depends({ [option_name("tcpbrutal")] = true }) o:depends({ [_n("tcpbrutal")] = true })
o = s:option(Value, option_name("tcpbrutal_down_mbps"), translate("Max download Mbps")) o = s:option(Value, _n("tcpbrutal_down_mbps"), translate("Max download Mbps"))
o.default = "50" o.default = "50"
o:depends({ [option_name("tcpbrutal")] = true }) o:depends({ [_n("tcpbrutal")] = true })
o = s:option(Flag, option_name("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) o = s:option(Flag, _n("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
o.default = "0" o.default = "0"
o = s:option(Flag, option_name("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!")) o = s:option(Flag, _n("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!"))
o.default = "0" o.default = "0"
local nodes_table = {} local nodes_table = {}
@ -391,46 +391,45 @@ for k, e in ipairs(api.get_valid_nodes()) do
end end
end end
o = s:option(ListValue, option_name("outbound_node"), translate("outbound node")) o = s:option(ListValue, _n("outbound_node"), translate("outbound node"))
o:value("nil", translate("Close")) o:value("", translate("Close"))
o:value("_socks", translate("Custom Socks")) o:value("_socks", translate("Custom Socks"))
o:value("_http", translate("Custom HTTP")) o:value("_http", translate("Custom HTTP"))
o:value("_iface", translate("Custom Interface")) o:value("_iface", translate("Custom Interface"))
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
o.default = "nil"
o = s:option(Value, option_name("outbound_node_address"), translate("Address (Support Domain Name)")) o = s:option(Value, _n("outbound_node_address"), translate("Address (Support Domain Name)"))
o:depends({ [option_name("outbound_node")] = "_socks" }) o:depends({ [_n("outbound_node")] = "_socks" })
o:depends({ [option_name("outbound_node")] = "_http" }) o:depends({ [_n("outbound_node")] = "_http" })
o = s:option(Value, option_name("outbound_node_port"), translate("Port")) o = s:option(Value, _n("outbound_node_port"), translate("Port"))
o.datatype = "port" o.datatype = "port"
o:depends({ [option_name("outbound_node")] = "_socks" }) o:depends({ [_n("outbound_node")] = "_socks" })
o:depends({ [option_name("outbound_node")] = "_http" }) o:depends({ [_n("outbound_node")] = "_http" })
o = s:option(Value, option_name("outbound_node_username"), translate("Username")) o = s:option(Value, _n("outbound_node_username"), translate("Username"))
o:depends({ [option_name("outbound_node")] = "_socks" }) o:depends({ [_n("outbound_node")] = "_socks" })
o:depends({ [option_name("outbound_node")] = "_http" }) o:depends({ [_n("outbound_node")] = "_http" })
o = s:option(Value, option_name("outbound_node_password"), translate("Password")) o = s:option(Value, _n("outbound_node_password"), translate("Password"))
o.password = true o.password = true
o:depends({ [option_name("outbound_node")] = "_socks" }) o:depends({ [_n("outbound_node")] = "_socks" })
o:depends({ [option_name("outbound_node")] = "_http" }) o:depends({ [_n("outbound_node")] = "_http" })
o = s:option(Value, option_name("outbound_node_iface"), translate("Interface")) o = s:option(Value, _n("outbound_node_iface"), translate("Interface"))
o.default = "eth1" o.default = "eth1"
o:depends({ [option_name("outbound_node")] = "_iface" }) o:depends({ [_n("outbound_node")] = "_iface" })
o = s:option(Flag, option_name("log"), translate("Log")) o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1" o.default = "1"
o.rmempty = false o.rmempty = false
o = s:option(ListValue, option_name("loglevel"), translate("Log Level")) o = s:option(ListValue, _n("loglevel"), translate("Log Level"))
o.default = "info" o.default = "info"
o:value("debug") o:value("debug")
o:value("info") o:value("info")
o:value("warn") o:value("warn")
o:value("error") o:value("error")
o:depends({ [option_name("log")] = true }) o:depends({ [_n("log")] = true })
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -10,7 +10,7 @@ local type_name = "Socks"
local option_prefix = "socks_" local option_prefix = "socks_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -18,14 +18,14 @@ end
s.fields["type"]:value(type_name, "Socks") s.fields["type"]:value(type_name, "Socks")
o = s:option(Value, option_name("port"), translate("Listen Port")) o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(Flag, option_name("auth"), translate("Auth")) o = s:option(Flag, _n("auth"), translate("Auth"))
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value and value == "1" then if value and value == "1" then
local user_v = s.fields[option_name("username")] and s.fields[option_name("username")]:formvalue(t) or "" local user_v = s.fields[_n("username")] and s.fields[_n("username")]:formvalue(t) or ""
local pass_v = s.fields[option_name("password")] and s.fields[option_name("password")]:formvalue(t) or "" local pass_v = s.fields[_n("password")] and s.fields[_n("password")]:formvalue(t) or ""
if user_v == "" or pass_v == "" then if user_v == "" or pass_v == "" then
return nil, translate("Username and Password must be used together!") return nil, translate("Username and Password must be used together!")
end end
@ -33,14 +33,14 @@ o.validate = function(self, value, t)
return value return value
end end
o = s:option(Value, option_name("username"), translate("Username")) o = s:option(Value, _n("username"), translate("Username"))
o:depends({ [option_name("auth")] = true }) o:depends({ [_n("auth")] = true })
o = s:option(Value, option_name("password"), translate("Password")) o = s:option(Value, _n("password"), translate("Password"))
o.password = true o.password = true
o:depends({ [option_name("auth")] = true }) o:depends({ [_n("auth")] = true })
o = s:option(Flag, option_name("log"), translate("Log")) o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1" o.default = "1"
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -10,7 +10,7 @@ local type_name = "SS-Rust"
local option_prefix = "ssrust_" local option_prefix = "ssrust_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -24,23 +24,23 @@ local ssrust_encrypt_method_list = {
s.fields["type"]:value(type_name, translate("Shadowsocks Rust")) s.fields["type"]:value(type_name, translate("Shadowsocks Rust"))
o = s:option(Value, option_name("port"), translate("Listen Port")) o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(Value, option_name("password"), translate("Password")) o = s:option(Value, _n("password"), translate("Password"))
o.password = true o.password = true
o = s:option(ListValue, option_name("method"), translate("Encrypt Method")) o = s:option(ListValue, _n("method"), translate("Encrypt Method"))
for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end
o = s:option(Value, option_name("timeout"), translate("Connection Timeout")) o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = 300 o.default = 300
o = s:option(Flag, option_name("tcp_fast_open"), "TCP " .. translate("Fast Open")) o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"))
o.default = "0" o.default = "0"
o = s:option(Flag, option_name("log"), translate("Log")) o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1" o.default = "1"
o.rmempty = false o.rmempty = false

View File

@ -10,7 +10,7 @@ local type_name = "SS"
local option_prefix = "ss_" local option_prefix = "ss_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -27,23 +27,23 @@ local ss_encrypt_method_list = {
s.fields["type"]:value(type_name, translate("Shadowsocks")) s.fields["type"]:value(type_name, translate("Shadowsocks"))
o = s:option(Value, option_name("port"), translate("Listen Port")) o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(Value, option_name("password"), translate("Password")) o = s:option(Value, _n("password"), translate("Password"))
o.password = true o.password = true
o = s:option(ListValue, option_name("method"), translate("Encrypt Method")) o = s:option(ListValue, _n("method"), translate("Encrypt Method"))
for a, t in ipairs(ss_encrypt_method_list) do o:value(t) end for a, t in ipairs(ss_encrypt_method_list) do o:value(t) end
o = s:option(Value, option_name("timeout"), translate("Connection Timeout")) o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = 300 o.default = 300
o = s:option(Flag, option_name("tcp_fast_open"), "TCP " .. translate("Fast Open")) o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"))
o.default = "0" o.default = "0"
o = s:option(Flag, option_name("log"), translate("Log")) o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1" o.default = "1"
o.rmempty = false o.rmempty = false

View File

@ -10,7 +10,7 @@ local type_name = "SSR"
local option_prefix = "ssr_" local option_prefix = "ssr_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -37,37 +37,37 @@ local ssr_obfs_list = {
s.fields["type"]:value(type_name, translate("ShadowsocksR")) s.fields["type"]:value(type_name, translate("ShadowsocksR"))
o = s:option(Value, option_name("port"), translate("Listen Port")) o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(Value, option_name("password"), translate("Password")) o = s:option(Value, _n("password"), translate("Password"))
o.password = true o.password = true
o = s:option(ListValue, option_name("method"), translate("Encrypt Method")) o = s:option(ListValue, _n("method"), translate("Encrypt Method"))
for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end
o = s:option(ListValue, option_name("protocol"), translate("Protocol")) o = s:option(ListValue, _n("protocol"), translate("Protocol"))
for a, t in ipairs(ssr_protocol_list) do o:value(t) end for a, t in ipairs(ssr_protocol_list) do o:value(t) end
o = s:option(Value, option_name("protocol_param"), translate("Protocol_param")) o = s:option(Value, _n("protocol_param"), translate("Protocol_param"))
o = s:option(ListValue, option_name("obfs"), translate("Obfs")) o = s:option(ListValue, _n("obfs"), translate("Obfs"))
for a, t in ipairs(ssr_obfs_list) do o:value(t) end for a, t in ipairs(ssr_obfs_list) do o:value(t) end
o = s:option(Value, option_name("obfs_param"), translate("Obfs_param")) o = s:option(Value, _n("obfs_param"), translate("Obfs_param"))
o = s:option(Value, option_name("timeout"), translate("Connection Timeout")) o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = 300 o.default = 300
o = s:option(Flag, option_name("tcp_fast_open"), "TCP " .. translate("Fast Open")) o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"))
o.default = "0" o.default = "0"
o = s:option(Flag, option_name("udp_forward"), translate("UDP Forward")) o = s:option(Flag, _n("udp_forward"), translate("UDP Forward"))
o.default = "1" o.default = "1"
o.rmempty = false o.rmempty = false
o = s:option(Flag, option_name("log"), translate("Log")) o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1" o.default = "1"
o.rmempty = false o.rmempty = false

View File

@ -10,7 +10,7 @@ local type_name = "Trojan-Plus"
local option_prefix = "trojan_plus_" local option_prefix = "trojan_plus_"
local function option_name(name) local function _n(name)
return option_prefix .. name return option_prefix .. name
end end
@ -18,15 +18,15 @@ end
s.fields["type"]:value(type_name, "Trojan-Plus") s.fields["type"]:value(type_name, "Trojan-Plus")
o = s:option(Value, option_name("port"), translate("Listen Port")) o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port" o.datatype = "port"
o = s:option(DynamicList, option_name("uuid"), translate("ID") .. "/" .. translate("Password")) o = s:option(DynamicList, _n("uuid"), translate("ID") .. "/" .. translate("Password"))
for i = 1, 3 do for i = 1, 3 do
o:value(api.gen_uuid(1)) o:value(api.gen_uuid(1))
end end
o = s:option(Flag, option_name("tls"), translate("TLS")) o = s:option(Flag, _n("tls"), translate("TLS"))
o.default = 0 o.default = 0
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value then if value then
@ -35,8 +35,8 @@ o.validate = function(self, value, t)
return nil, translate("Original Trojan only supported 'tls', please choose 'tls'.") return nil, translate("Original Trojan only supported 'tls', please choose 'tls'.")
end end
if value == "1" then if value == "1" then
local ca = s.fields[option_name("tls_certificateFile")] and s.fields[option_name("tls_certificateFile")]:formvalue(t) or "" local ca = s.fields[_n("tls_certificateFile")] and s.fields[_n("tls_certificateFile")]:formvalue(t) or ""
local key = s.fields[option_name("tls_keyFile")] and s.fields[option_name("tls_keyFile")]:formvalue(t) or "" local key = s.fields[_n("tls_keyFile")] and s.fields[_n("tls_keyFile")]:formvalue(t) or ""
if ca == "" or key == "" then if ca == "" or key == "" then
return nil, translate("Public key and Private key path can not be empty!") return nil, translate("Public key and Private key path can not be empty!")
end end
@ -45,9 +45,9 @@ o.validate = function(self, value, t)
end end
end end
o = s:option(FileUpload, option_name("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem") o = s:option(FileUpload, _n("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem" o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem"
o:depends({ [option_name("tls")] = true }) o:depends({ [_n("tls")] = true })
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value and value ~= "" then if value and value ~= "" then
if not nixio.fs.access(value) then if not nixio.fs.access(value) then
@ -59,9 +59,9 @@ o.validate = function(self, value, t)
return nil return nil
end end
o = s:option(FileUpload, option_name("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key") o = s:option(FileUpload, _n("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key" o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key"
o:depends({ [option_name("tls")] = true }) o:depends({ [_n("tls")] = true })
o.validate = function(self, value, t) o.validate = function(self, value, t)
if value and value ~= "" then if value and value ~= "" then
if not nixio.fs.access(value) then if not nixio.fs.access(value) then
@ -73,36 +73,36 @@ o.validate = function(self, value, t)
return nil return nil
end end
o = s:option(Flag, option_name("tls_sessionTicket"), translate("Session Ticket")) o = s:option(Flag, _n("tls_sessionTicket"), translate("Session Ticket"))
o.default = "0" o.default = "0"
o:depends({ [option_name("tls")] = true }) o:depends({ [_n("tls")] = true })
o = s:option(Flag, option_name("tcp_fast_open"), translate("TCP Fast Open")) o = s:option(Flag, _n("tcp_fast_open"), translate("TCP Fast Open"))
o.default = "0" o.default = "0"
o = s:option(Flag, option_name("remote_enable"), translate("Enable Remote"), translate("You can forward to Nginx/Caddy/V2ray/Xray WebSocket and more.")) o = s:option(Flag, _n("remote_enable"), translate("Enable Remote"), translate("You can forward to Nginx/Caddy/V2ray/Xray WebSocket and more."))
o.default = "1" o.default = "1"
o.rmempty = false o.rmempty = false
o = s:option(Value, option_name("remote_address"), translate("Remote Address")) o = s:option(Value, _n("remote_address"), translate("Remote Address"))
o.default = "127.0.0.1" o.default = "127.0.0.1"
o:depends({ [option_name("remote_enable")] = true }) o:depends({ [_n("remote_enable")] = true })
o = s:option(Value, option_name("remote_port"), translate("Remote Port")) o = s:option(Value, _n("remote_port"), translate("Remote Port"))
o.datatype = "port" o.datatype = "port"
o.default = "80" o.default = "80"
o:depends({ [option_name("remote_enable")] = true }) o:depends({ [_n("remote_enable")] = true })
o = s:option(Flag, option_name("log"), translate("Log")) o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1" o.default = "1"
o = s:option(ListValue, option_name("loglevel"), translate("Log Level")) o = s:option(ListValue, _n("loglevel"), translate("Log Level"))
o.default = "2" o.default = "2"
o:value("0", "all") o:value("0", "all")
o:value("1", "info") o:value("1", "info")
o:value("2", "warn") o:value("2", "warn")
o:value("3", "error") o:value("3", "error")
o:value("4", "fatal") o:value("4", "fatal")
o:depends({ [option_name("log")] = true }) o:depends({ [_n("log")] = true })
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -364,6 +364,26 @@ function get_domain_from_url(url)
return url return url
end end
function get_node_name(node_id)
local e
if type(node_id) == "table" then
e = node_id
else
e = uci:get_all(appname, node_id)
end
if e then
if e.type and e.remarks then
if e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface") then
local type = e.type
if type == "sing-box" then type = "Sing-Box" end
local remark = "%s[%s] " % {type .. " " .. i18n.translatef(e.protocol), e.remarks}
return remark
end
end
end
return ""
end
function get_valid_nodes() function get_valid_nodes()
local show_node_info = uci_get_type("global_other", "show_node_info") or "0" local show_node_info = uci_get_type("global_other", "show_node_info") or "0"
local nodes = {} local nodes = {}

View File

@ -20,7 +20,7 @@ end
function gen_outbound(flag, node, tag, proxy_table) function gen_outbound(flag, node, tag, proxy_table)
local result = nil local result = nil
if node and node ~= "nil" then if node then
local node_id = node[".name"] local node_id = node[".name"]
if tag == nil then if tag == nil then
tag = node_id tag = node_id
@ -46,7 +46,7 @@ function gen_outbound(flag, node, tag, proxy_table)
"127.0.0.1", --bind "127.0.0.1", --bind
new_port, --socks port new_port, --socks port
config_file, --config file config_file, --config file
(proxy_tag and proxy_tag ~= "nil" and relay_port) and tostring(relay_port) or "" --relay port (proxy_tag and relay_port) and tostring(relay_port) or "" --relay port
) )
) )
) )
@ -56,7 +56,7 @@ function gen_outbound(flag, node, tag, proxy_table)
port = new_port port = new_port
} }
else else
if proxy_tag and proxy_tag ~= "nil" then if proxy_tag then
node.detour = proxy_tag node.detour = proxy_tag
end end
end end
@ -679,7 +679,7 @@ function gen_config_server(node)
} }
} }
if node.outbound_node and node.outbound_node ~= "nil" then if node.outbound_node then
local outbound = nil local outbound = nil
if node.outbound_node == "_iface" and node.outbound_node_iface then if node.outbound_node == "_iface" and node.outbound_node_iface then
outbound = { outbound = {
@ -905,7 +905,7 @@ function gen_config(var)
end end
if node.chain_proxy == "1" and node.preproxy_node then if node.chain_proxy == "1" and node.preproxy_node then
if outbound["_flag_proxy_tag"] and outbound["_flag_proxy_tag"] ~= "nil" then if outbound["_flag_proxy_tag"] then
--Ignore --Ignore
else else
local preproxy_node = uci:get_all(appname, node.preproxy_node) local preproxy_node = uci:get_all(appname, node.preproxy_node)
@ -951,7 +951,7 @@ function gen_config(var)
local function gen_shunt_node(rule_name, _node_id) local function gen_shunt_node(rule_name, _node_id)
if not rule_name then return nil, nil end if not rule_name then return nil, nil end
if not _node_id then _node_id = node[rule_name] or "nil" end if not _node_id then _node_id = node[rule_name] end
local rule_outboundTag local rule_outboundTag
if _node_id == "_direct" then if _node_id == "_direct" then
rule_outboundTag = "direct" rule_outboundTag = "direct"
@ -976,7 +976,7 @@ function gen_config(var)
rule_outboundTag = _outbound.tag rule_outboundTag = _outbound.tag
end end
end end
elseif _node_id ~= "nil" then elseif _node_id then
local _node = uci:get_all(appname, _node_id) local _node = uci:get_all(appname, _node_id)
if not _node then return nil, nil end if not _node then return nil, nil end
@ -1180,7 +1180,7 @@ function gen_config(var)
rule.domain_regex = #domain_table.domain_regex > 0 and domain_table.domain_regex or nil rule.domain_regex = #domain_table.domain_regex > 0 and domain_table.domain_regex or nil
rule.geosite = #domain_table.geosite > 0 and domain_table.geosite or nil rule.geosite = #domain_table.geosite > 0 and domain_table.geosite or nil
if outboundTag and outboundTag ~= "nil" then if outboundTag then
table.insert(dns_domain_rules, api.clone(domain_table)) table.insert(dns_domain_rules, api.clone(domain_table))
end end
end end
@ -1476,7 +1476,7 @@ function gen_config(var)
tag = "block" tag = "block"
}) })
for index, value in ipairs(config.outbounds) do for index, value in ipairs(config.outbounds) do
if (not value["_flag_proxy_tag"] or value["_flag_proxy_tag"] == "nil") and not value.detour and value["_id"] and value.server and value.server_port then if not value["_flag_proxy_tag"] and not value.detour and value["_id"] and value.server and value.server_port then
sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list")) sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list"))
end end
for k, v in pairs(config.outbounds[index]) do for k, v in pairs(config.outbounds[index]) do

View File

@ -48,7 +48,7 @@ end
function gen_outbound(flag, node, tag, proxy_table) function gen_outbound(flag, node, tag, proxy_table)
local result = nil local result = nil
if node and node ~= "nil" then if node then
local node_id = node[".name"] local node_id = node[".name"]
if tag == nil then if tag == nil then
tag = node_id tag = node_id
@ -82,7 +82,7 @@ function gen_outbound(flag, node, tag, proxy_table)
"127.0.0.1", --bind "127.0.0.1", --bind
new_port, --socks port new_port, --socks port
config_file, --config file config_file, --config file
(proxy_tag and proxy_tag ~= "nil" and relay_port) and tostring(relay_port) or "" --relay port (proxy_tag and relay_port) and tostring(relay_port) or "" --relay port
) )
)) ))
node = {} node = {}
@ -95,7 +95,7 @@ function gen_outbound(flag, node, tag, proxy_table)
else else
if node.flow == "xtls-rprx-vision" then if node.flow == "xtls-rprx-vision" then
else else
if proxy_tag and proxy_tag ~= "nil" then if proxy_tag then
node.proxySettings = { node.proxySettings = {
tag = proxy_tag, tag = proxy_tag,
transportLayer = true transportLayer = true
@ -404,7 +404,7 @@ function gen_config_server(node)
} }
} }
if node.outbound_node and node.outbound_node ~= "nil" then if node.outbound_node then
local outbound = nil local outbound = nil
if node.outbound_node == "_iface" and node.outbound_node_iface then if node.outbound_node == "_iface" and node.outbound_node_iface then
outbound = { outbound = {
@ -735,7 +735,7 @@ function gen_config(var)
-- fallback node -- fallback node
local fallback_node_tag = nil local fallback_node_tag = nil
local fallback_node_id = _node.fallback_node local fallback_node_id = _node.fallback_node
if fallback_node_id == "" or fallback_node_id == "nil" then fallback_node_id = nil end if not fallback_node_id or fallback_node_id == "" then fallback_node_id = nil end
if fallback_node_id then if fallback_node_id then
local is_new_node = true local is_new_node = true
for _, outbound in ipairs(outbounds) do for _, outbound in ipairs(outbounds) do
@ -784,7 +784,7 @@ function gen_config(var)
local last_insert_outbound local last_insert_outbound
if node.chain_proxy == "1" and node.preproxy_node then if node.chain_proxy == "1" and node.preproxy_node then
if outbound["_flag_proxy_tag"] and outbound["_flag_proxy_tag"] ~= "nil" then if outbound["_flag_proxy_tag"] then
--Ignore --Ignore
else else
local preproxy_node = uci:get_all(appname, node.preproxy_node) local preproxy_node = uci:get_all(appname, node.preproxy_node)
@ -1396,7 +1396,7 @@ function gen_config(var)
end end
for index, value in ipairs(config.outbounds) do for index, value in ipairs(config.outbounds) do
if (not value["_flag_proxy_tag"] or value["_flag_proxy_tag"] == "nil") and value["_id"] and value.server and value.server_port then if not value["_flag_proxy_tag"] and value["_id"] and value.server and value.server_port then
sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list")) sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list"))
end end
for k, v in pairs(config.outbounds[index]) do for k, v in pairs(config.outbounds[index]) do

View File

@ -0,0 +1,3 @@
<div id="cbi-<%=self.config.."-"..section.."-"..self.option%>" data-index="<%=self.index%>" data-depends="<%=pcdata(self:deplist2json(section))%>" style="display: none !important">
<input type="hidden" id="<%=cbid%>" value="<%=pcdata(self:cfgvalue(section) or self.default or "")%>" />
</div>

View File

@ -53,13 +53,13 @@ local api = require "luci.passwall.api"
var dom_id = dom.id.split(cbi_id).join(cbi_id.split("-").join(".")).split("cbi.").join("cbid.") var dom_id = dom.id.split(cbi_id).join(cbi_id.split("-").join(".")).split("cbi.").join("cbid.")
var node_select = document.getElementsByName(dom_id)[0]; var node_select = document.getElementsByName(dom_id)[0];
var node_select_value = node_select.value; var node_select_value = node_select.value;
if (node_select_value && node_select_value != "nil" && node_select_value.indexOf("_default") != 0 && node_select_value.indexOf("_direct") != 0 && node_select_value.indexOf("_blackhole") != 0) { if (node_select_value && node_select_value != "" && node_select_value.indexOf("_default") != 0 && node_select_value.indexOf("_direct") != 0 && node_select_value.indexOf("_blackhole") != 0) {
if (global_id != null && node_select_value.indexOf("tcp") == 0) { if (global_id != null && node_select_value.indexOf("tcp") == 0) {
var d = global_id + "-tcp_node"; var d = global_id + "-tcp_node";
d = d.replace("cbi-", "cbid-").replace(new RegExp("-", 'g'), "."); d = d.replace("cbi-", "cbid-").replace(new RegExp("-", 'g'), ".");
var dom = document.getElementsByName(d)[0]; var dom = document.getElementsByName(d)[0];
var _node_select_value = dom.value; var _node_select_value = dom.value;
if (_node_select_value && _node_select_value != "nil") { if (_node_select_value && _node_select_value != "") {
node_select_value = _node_select_value; node_select_value = _node_select_value;
} }
} }
@ -117,7 +117,7 @@ local api = require "luci.passwall.api"
var dom_id = dom_id.replace("cbi-", "cbid-").replace(new RegExp("-", 'g'), "."); var dom_id = dom_id.replace("cbi-", "cbid-").replace(new RegExp("-", 'g'), ".");
var node_select = document.getElementsByName(dom_id)[0]; var node_select = document.getElementsByName(dom_id)[0];
var node_select_value = node_select.value; var node_select_value = node_select.value;
if (node_select_value && node_select_value != "nil") { if (node_select_value && node_select_value != "") {
var v = document.getElementById(dom_id + "-" + node_select_value); var v = document.getElementById(dom_id + "-" + node_select_value);
if (v) { if (v) {
node_select.title = v.text; node_select.title = v.text;

View File

@ -673,17 +673,32 @@ msgstr "单位:秒"
msgid "Units:minutes" msgid "Units:minutes"
msgstr "单位:分钟" msgstr "单位:分钟"
msgid "Open and close automatically" msgid "stop automatically mode"
msgstr "定时自动开关" msgstr "定时关闭模式"
msgid "Automatically turn off time" msgid "stop Time(Every day)"
msgstr "自动关闭时间" msgstr "关闭时间(每天)"
msgid "Automatically turn on time" msgid "stop Interval(Hour)"
msgstr "自动开启时间" msgstr "关闭间隔(小时)"
msgid "Automatically restart time" msgid "start automatically mode"
msgstr "自动重启时间" msgstr "定时开启模式"
msgid "start Time(Every day)"
msgstr "开启时间(每天)"
msgid "start Interval(Hour)"
msgstr "开启间隔(小时)"
msgid "restart automatically mode"
msgstr "定时重启模式"
msgid "restart Time(Every day)"
msgstr "重启时间(每天)"
msgid "restart Interval(Hour)"
msgstr "重启间隔(小时)"
msgid "Forwarding Settings" msgid "Forwarding Settings"
msgstr "转发配置" msgstr "转发配置"
@ -925,6 +940,9 @@ msgstr "每周日"
msgid "hour" msgid "hour"
msgstr "小时" msgstr "小时"
msgid "Hour"
msgstr "小时"
msgid "Location of V2ray/Xray asset" msgid "Location of V2ray/Xray asset"
msgstr "V2ray/Xray 资源文件目录" msgstr "V2ray/Xray 资源文件目录"

View File

@ -2,8 +2,6 @@
config global config global
option enabled '0' option enabled '0'
option socks_enabled '0' option socks_enabled '0'
option tcp_node 'nil'
option udp_node 'nil'
option tcp_node_socks_port '1070' option tcp_node_socks_port '1070'
option filter_proxy_ipv6 '1' option filter_proxy_ipv6 '1'
option dns_shunt 'chinadns-ng' option dns_shunt 'chinadns-ng'
@ -32,7 +30,6 @@ config global_haproxy
option balancing_enable '0' option balancing_enable '0'
config global_delay config global_delay
option auto_on '0'
option start_daemon '1' option start_daemon '1'
option start_delay '15' option start_delay '15'
@ -102,7 +99,7 @@ config nodes 'myshunt'
option Streaming '_default' option Streaming '_default'
option Proxy '_default' option Proxy '_default'
option Direct '_direct' option Direct '_direct'
option default_node 'nil' option default_node '_direct'
option domainStrategy 'IPOnDemand' option domainStrategy 'IPOnDemand'
config shunt_rules 'DirectGame' config shunt_rules 'DirectGame'

View File

@ -707,7 +707,7 @@ run_socks() {
;; ;;
esac esac
eval node_${node}_socks_port=$socks_port set_cache_var "node_${node}_socks_port" "${socks_port}"
# http to socks # http to socks
[ -z "$http_flag" ] && [ "$http_port" != "0" ] && [ -n "$http_config_file" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && [ "$type" != "socks" ] && { [ -z "$http_flag" ] && [ "$http_port" != "0" ] && [ -n "$http_config_file" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && [ "$type" != "socks" ] && {
@ -755,7 +755,7 @@ run_redir() {
} }
} }
[ "$bind" != "127.0.0.1" ] && echolog "${PROTO}节点:[$remarks],监听端口:$local_port" [ "$bind" != "127.0.0.1" ] && echolog "${PROTO}节点:[$remarks],监听端口:$local_port"
eval ${PROTO}_NODE_PORT=$port set_cache_var "${PROTO}_NODE_PORT" "${port}"
case "$PROTO" in case "$PROTO" in
UDP) UDP)
@ -856,7 +856,7 @@ run_redir() {
} }
[ "$TCP_UDP" = "1" ] && { [ "$TCP_UDP" = "1" ] && {
UDP_REDIR_PORT=$local_port UDP_REDIR_PORT=$local_port
UDP_NODE="nil" unset UDP_NODE
_flag="TCP_UDP" _flag="TCP_UDP"
_args="${_args} udp_redir_port=${UDP_REDIR_PORT}" _args="${_args} udp_redir_port=${UDP_REDIR_PORT}"
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g") config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
@ -932,7 +932,7 @@ run_redir() {
} }
[ "$TCP_UDP" = "1" ] && { [ "$TCP_UDP" = "1" ] && {
UDP_REDIR_PORT=$local_port UDP_REDIR_PORT=$local_port
UDP_NODE="nil" unset UDP_NODE
_flag="TCP_UDP" _flag="TCP_UDP"
_args="${_args} udp_redir_port=${UDP_REDIR_PORT}" _args="${_args} udp_redir_port=${UDP_REDIR_PORT}"
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g") config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
@ -974,7 +974,7 @@ run_redir() {
[ "$TCP_UDP" = "1" ] && { [ "$TCP_UDP" = "1" ] && {
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g") config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
UDP_REDIR_PORT=$TCP_REDIR_PORT UDP_REDIR_PORT=$TCP_REDIR_PORT
UDP_NODE="nil" unset UDP_NODE
} }
local loglevel=$(config_t_get global trojan_loglevel "2") local loglevel=$(config_t_get global trojan_loglevel "2")
lua $UTIL_TROJAN gen_config -node $node -run_type nat -local_addr "0.0.0.0" -local_port $local_port -loglevel $loglevel $lua_tproxy_arg > $config_file lua $UTIL_TROJAN gen_config -node $node -run_type nat -local_addr "0.0.0.0" -local_port $local_port -loglevel $loglevel $lua_tproxy_arg > $config_file
@ -989,7 +989,7 @@ run_redir() {
[ "$TCP_UDP" = "1" ] && { [ "$TCP_UDP" = "1" ] && {
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g") config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
UDP_REDIR_PORT=$TCP_REDIR_PORT UDP_REDIR_PORT=$TCP_REDIR_PORT
UDP_NODE="nil" unset UDP_NODE
_extra_param="-u" _extra_param="-u"
} }
lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $local_port $lua_tproxy_arg > $config_file lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $local_port $lua_tproxy_arg > $config_file
@ -1001,7 +1001,7 @@ run_redir() {
[ "$TCP_UDP" = "1" ] && { [ "$TCP_UDP" = "1" ] && {
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g") config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
UDP_REDIR_PORT=$TCP_REDIR_PORT UDP_REDIR_PORT=$TCP_REDIR_PORT
UDP_NODE="nil" unset UDP_NODE
lua_mode_arg="-mode tcp_and_udp" lua_mode_arg="-mode tcp_and_udp"
} }
lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $local_port $lua_mode_arg $lua_tproxy_arg > $config_file lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $local_port $lua_mode_arg $lua_tproxy_arg > $config_file
@ -1023,7 +1023,7 @@ run_redir() {
[ "$TCP_UDP" = "1" ] && { [ "$TCP_UDP" = "1" ] && {
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g") config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
UDP_REDIR_PORT=$TCP_REDIR_PORT UDP_REDIR_PORT=$TCP_REDIR_PORT
UDP_NODE="nil" unset UDP_NODE
_extra_param="${_extra_param} -local_udp_redir_port $local_port" _extra_param="${_extra_param} -local_udp_redir_port $local_port"
} }
lua $UTIL_SS gen_config -node $node ${_extra_param} > $config_file lua $UTIL_SS gen_config -node $node ${_extra_param} > $config_file
@ -1044,7 +1044,7 @@ run_redir() {
[ "$TCP_UDP" = "1" ] && { [ "$TCP_UDP" = "1" ] && {
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g") config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
UDP_REDIR_PORT=$TCP_REDIR_PORT UDP_REDIR_PORT=$TCP_REDIR_PORT
UDP_NODE="nil" unset UDP_NODE
_extra_param="${_extra_param} -local_udp_redir_port $local_port" _extra_param="${_extra_param} -local_udp_redir_port $local_port"
} }
_extra_param="${_extra_param} -tcp_proxy_way $tcp_proxy_way" _extra_param="${_extra_param} -tcp_proxy_way $tcp_proxy_way"
@ -1057,7 +1057,7 @@ run_redir() {
[ "$TCP_UDP" = "1" ] && { [ "$TCP_UDP" = "1" ] && {
_flag="TCP_UDP" _flag="TCP_UDP"
UDP_REDIR_PORT=$TCP_REDIR_PORT UDP_REDIR_PORT=$TCP_REDIR_PORT
UDP_NODE="nil" unset UDP_NODE
} }
local _socks_tproxy="" local _socks_tproxy=""
[ "$tcp_proxy_way" = "tproxy" ] && _socks_tproxy="1" [ "$tcp_proxy_way" = "tproxy" ] && _socks_tproxy="1"
@ -1085,13 +1085,13 @@ run_redir() {
esac esac
unset tcp_node_socks_flag tcp_node_http_flag unset tcp_node_socks_flag tcp_node_http_flag
[ "$type" != "sing-box" ] && [ "$type" != "xray" ] && echo "${node}" >> $TMP_PATH/direct_node_list [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && echo "${node}" >> $TMP_PATH/direct_node_list
return 0 [ -n "${redir_port}" ] && set_cache_var "node_${node}_${PROTO}_redir_port" "${local_port}"
} }
start_redir() { start_redir() {
local proto=${1} local proto=${1}
eval node=\$${proto}_NODE eval node=\$${proto}_NODE
if [ "$node" != "nil" ]; then if [ -n "$node" ]; then
TYPE=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z') TYPE=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
local config_file="${proto}.json" local config_file="${proto}.json"
local log_file="${proto}.log" local log_file="${proto}.log"
@ -1099,7 +1099,12 @@ start_redir() {
local port=$(echo $(get_new_port $current_port $proto)) local port=$(echo $(get_new_port $current_port $proto))
eval ${proto}_REDIR=$port eval ${proto}_REDIR=$port
run_redir node=$node proto=${proto} bind=0.0.0.0 local_port=$port config_file=$config_file log_file=$log_file run_redir node=$node proto=${proto} bind=0.0.0.0 local_port=$port config_file=$config_file log_file=$log_file
set_cache_var "GLOBAL_${proto}_node" "$node" set_cache_var "ACL_GLOBAL_${proto}_node" "${node}"
set_cache_var "ACL_GLOBAL_${proto}_redir_port" "${port}"
[ "$TCP_UDP" = "1" ] && {
set_cache_var "ACL_GLOBAL_UDP_node" "${node}"
set_cache_var "ACL_GLOBAL_UDP_redir_port" "${port}"
}
else else
[ "${proto}" = "UDP" ] && [ "$TCP_UDP" = "1" ] && return [ "${proto}" = "UDP" ] && [ "$TCP_UDP" = "1" ] && return
echolog "${proto}节点没有选择或为空,不代理${proto}" echolog "${proto}节点没有选择或为空,不代理${proto}"
@ -1114,8 +1119,8 @@ start_socks() {
for id in $ids; do for id in $ids; do
local enabled=$(config_n_get $id enabled 0) local enabled=$(config_n_get $id enabled 0)
[ "$enabled" == "0" ] && continue [ "$enabled" == "0" ] && continue
local node=$(config_n_get $id node nil) local node=$(config_n_get $id node)
[ "$node" == "nil" ] && continue [ -z "$node" ] && continue
local bind_local=$(config_n_get $id bind_local 0) local bind_local=$(config_n_get $id bind_local 0)
local bind="0.0.0.0" local bind="0.0.0.0"
[ "$bind_local" = "1" ] && bind="127.0.0.1" [ "$bind_local" = "1" ] && bind="127.0.0.1"
@ -1206,23 +1211,41 @@ start_crontab() {
return return
} }
auto_on=$(config_t_get global_delay auto_on 0) stop_week_mode=$(config_t_get global_delay stop_week_mode)
if [ "$auto_on" = "1" ]; then stop_time_mode=$(config_t_get global_delay stop_time_mode)
time_off=$(config_t_get global_delay time_off) if [ -n "$stop_week_mode" ]; then
time_on=$(config_t_get global_delay time_on) local t="0 $stop_time_mode * * $stop_week_mode"
time_restart=$(config_t_get global_delay time_restart) [ "$stop_week_mode" = "7" ] && t="0 $stop_time_mode * * *"
[ -z "$time_off" -o "$time_off" != "nil" ] && { if [ "$stop_week_mode" = "8" ]; then
echo "0 $time_off * * * /etc/init.d/$CONFIG stop" >>/etc/crontabs/root update_loop=1
echolog "配置定时任务:每天 $time_off 点关闭服务。" else
} echo "$t /etc/init.d/$CONFIG stop > /dev/null 2>&1 &" >>/etc/crontabs/root
[ -z "$time_on" -o "$time_on" != "nil" ] && { fi
echo "0 $time_on * * * /etc/init.d/$CONFIG start" >>/etc/crontabs/root echolog "配置定时任务:自动关闭服务。"
echolog "配置定时任务:每天 $time_on 点开启服务。" fi
} start_week_mode=$(config_t_get global_delay start_week_mode)
[ -z "$time_restart" -o "$time_restart" != "nil" ] && { start_time_mode=$(config_t_get global_delay start_time_mode)
echo "0 $time_restart * * * /etc/init.d/$CONFIG restart" >>/etc/crontabs/root if [ -n "$start_week_mode" ]; then
echolog "配置定时任务:每天 $time_restart 点重启服务。" local t="0 $start_time_mode * * $start_week_mode"
} [ "$start_week_mode" = "7" ] && t="0 $start_time_mode * * *"
if [ "$start_week_mode" = "8" ]; then
update_loop=1
else
echo "$t /etc/init.d/$CONFIG start > /dev/null 2>&1 &" >>/etc/crontabs/root
fi
echolog "配置定时任务:自动开启服务。"
fi
restart_week_mode=$(config_t_get global_delay restart_week_mode)
restart_time_mode=$(config_t_get global_delay restart_time_mode)
if [ -n "$restart_week_mode" ]; then
local t="0 $restart_time_mode * * $restart_week_mode"
[ "$restart_week_mode" = "7" ] && t="0 $restart_time_mode * * *"
if [ "$restart_week_mode" = "8" ]; then
update_loop=1
else
echo "$t /etc/init.d/$CONFIG restart > /dev/null 2>&1 &" >>/etc/crontabs/root
fi
echolog "配置定时任务:自动重启服务。"
fi fi
autoupdate=$(config_t_get global_rules auto_update) autoupdate=$(config_t_get global_rules auto_update)
@ -1695,8 +1718,17 @@ acl_app() {
[ ! -z "${source_list}" ] && echo -e "${source_list}" | sed '/^$/d' > ${acl_path}/source_list [ ! -z "${source_list}" ] && echo -e "${source_list}" | sed '/^$/d' > ${acl_path}/source_list
use_global_config=${use_global_config:-0} use_global_config=${use_global_config:-0}
tcp_node=${tcp_node:-nil} [ "${use_global_config}" = "1" ] && {
udp_node=${udp_node:-nil} tcp_node="default"
udp_node="default"
}
tcp_no_redir_ports=${tcp_no_redir_ports:-${TCP_NO_REDIR_PORTS}}
udp_no_redir_ports=${udp_no_redir_ports:-${UDP_NO_REDIR_PORTS}}
if [ "$tcp_no_redir_ports" == "1:65535" ] && [ "$udp_no_redir_ports" == "1:65535" ]; then
unset use_global_config
unset tcp_node
unset udp_node
else
use_direct_list=${use_direct_list:-1} use_direct_list=${use_direct_list:-1}
use_proxy_list=${use_proxy_list:-1} use_proxy_list=${use_proxy_list:-1}
use_block_list=${use_block_list:-1} use_block_list=${use_block_list:-1}
@ -1713,18 +1745,29 @@ acl_app() {
[ "$dns_mode" = "sing-box" ] && { [ "$dns_mode" = "sing-box" ] && {
[ "$v2ray_dns_mode" = "doh" ] && remote_dns=${remote_dns_doh:-https://1.1.1.1/dns-query} [ "$v2ray_dns_mode" = "doh" ] && remote_dns=${remote_dns_doh:-https://1.1.1.1/dns-query}
} }
fi
[ "${use_global_config}" = "1" ] && { [ -n "$tcp_node" ] && {
tcp_node="default" local GLOBAL_TCP_NODE=$(get_cache_var "ACL_GLOBAL_TCP_node")
udp_node="default" echolog "${GLOBAL_TCP_NODE}"
} [ -n "${GLOBAL_TCP_NODE}" ] && GLOBAL_TCP_redir_port=$(get_cache_var "ACL_GLOBAL_TCP_redir_port")
[ "$tcp_node" != "nil" ] && {
if [ "$tcp_node" = "default" ]; then if [ "$tcp_node" = "default" ]; then
tcp_node=$TCP_NODE if [ -n "${GLOBAL_TCP_NODE}" ]; then
tcp_port=$TCP_REDIR_PORT set_cache_var "ACL_${sid}_tcp_node" "${GLOBAL_TCP_NODE}"
set_cache_var "ACL_${sid}_tcp_redir_port" "${GLOBAL_TCP_redir_port}"
set_cache_var "ACL_${sid}_dns_port" "${GLOBAL_DNSMASQ_PORT}"
set_cache_var "ACL_${sid}_tcp_default" "1"
else
echolog " - 全局节点未启用,跳过【${remarks}"
fi
else
[ "$(config_get_type $tcp_node)" = "nodes" ] && {
if [ -n "${GLOBAL_TCP_NODE}" ] && [ "$tcp_node" = "${GLOBAL_TCP_NODE}" ]; then
set_cache_var "ACL_${sid}_tcp_node" "${GLOBAL_TCP_NODE}"
set_cache_var "ACL_${sid}_tcp_redir_port" "${GLOBAL_TCP_redir_port}"
set_cache_var "ACL_${sid}_dns_port" "${GLOBAL_DNSMASQ_PORT}"
set_cache_var "ACL_${sid}_tcp_default" "1"
else else
[ "$(config_get_type $tcp_node nil)" = "nodes" ] && {
run_dns() { run_dns() {
local _dns_port local _dns_port
[ -n $1 ] && _dns_port=$1 [ -n $1 ] && _dns_port=$1
@ -1741,7 +1784,7 @@ acl_app() {
dnsmasq_filter_proxy_ipv6=0 dnsmasq_filter_proxy_ipv6=0
run_${type} flag=acl_${sid} type=$dns_mode dns_socks_address=127.0.0.1 dns_socks_port=$socks_port dns_listen_port=${_dns_port} remote_dns_protocol=${v2ray_dns_mode} remote_dns_tcp_server=${remote_dns} remote_dns_doh="${remote_dns_doh}" remote_dns_query_strategy=${DNS_QUERY_STRATEGY} dns_client_ip=${dns_client_ip} dns_query_strategy=${DNS_QUERY_STRATEGY} config_file=$config_file run_${type} flag=acl_${sid} type=$dns_mode dns_socks_address=127.0.0.1 dns_socks_port=$socks_port dns_listen_port=${_dns_port} remote_dns_protocol=${v2ray_dns_mode} remote_dns_tcp_server=${remote_dns} remote_dns_doh="${remote_dns_doh}" remote_dns_query_strategy=${DNS_QUERY_STRATEGY} dns_client_ip=${dns_client_ip} dns_query_strategy=${DNS_QUERY_STRATEGY} config_file=$config_file
fi fi
eval node_${tcp_node}_$(echo -n "${remote_dns}" | md5sum | cut -d " " -f1)=${_dns_port} set_cache_var "node_${tcp_node}_$(echo -n "${remote_dns}" | md5sum | cut -d " " -f1)" "${_dns_port}"
} }
[ "$dns_shunt" = "chinadns-ng" ] && [ -n "$(first_type chinadns-ng)" ] && { [ "$dns_shunt" = "chinadns-ng" ] && [ -n "$(first_type chinadns-ng)" ] && {
@ -1801,25 +1844,25 @@ acl_app() {
-NO_LOGIC_LOG 1 -NO_LOGIC_LOG 1
ln_run "$(first_type dnsmasq)" "dnsmasq_${sid}" "/dev/null" -C ${dnsmasq_conf} -x ${acl_path}/dnsmasq.pid ln_run "$(first_type dnsmasq)" "dnsmasq_${sid}" "/dev/null" -C ${dnsmasq_conf} -x ${acl_path}/dnsmasq.pid
set_cache_var "ACL_${sid}_dns_port" "${dnsmasq_port}" set_cache_var "ACL_${sid}_dns_port" "${dnsmasq_port}"
eval node_${tcp_node}_$(echo -n "${tcp_proxy_mode}${remote_dns}" | md5sum | cut -d " " -f1)=${dnsmasq_port} set_cache_var "node_${tcp_node}_$(echo -n "${tcp_proxy_mode}${remote_dns}" | md5sum | cut -d " " -f1)" "${dnsmasq_port}"
} }
_redir_port=$(eval echo \${node_${tcp_node}_redir_port}) _redir_port=$(get_cache_var "node_${tcp_node}_redir_port")
_socks_port=$(eval echo \${node_${tcp_node}_socks_port}) _socks_port=$(get_cache_var "node_${tcp_node}_socks_port")
if [ -n "${_socks_port}" ] && [ -n "${_redir_port}" ]; then if [ -n "${_socks_port}" ] && [ -n "${_redir_port}" ]; then
socks_port=${_socks_port} socks_port=${_socks_port}
tcp_port=${_redir_port} tcp_port=${_redir_port}
_dnsmasq_port=$(eval echo \${node_${tcp_node}_$(echo -n "${tcp_proxy_mode}${remote_dns}" | md5sum | cut -d " " -f1)}) _dnsmasq_port=$(get_cache_var "node_${tcp_node}_$(echo -n "${tcp_proxy_mode}${remote_dns}" | md5sum | cut -d " " -f1)")
if [ -z "${_dnsmasq_port}" ]; then if [ -z "${_dnsmasq_port}" ]; then
_dns_port=$(eval echo \${node_${tcp_node}_$(echo -n "${remote_dns}" | md5sum | cut -d " " -f1)}) _dns_port=$(get_cache_var "node_${tcp_node}_$(echo -n "${remote_dns}" | md5sum | cut -d " " -f1)")
run_dns ${_dns_port} run_dns ${_dns_port}
else else
[ -n "${_dnsmasq_port}" ] && set_cache_var "ACL_${sid}_dns_port" "${_dnsmasq_port}" [ -n "${_dnsmasq_port}" ] && set_cache_var "ACL_${sid}_dns_port" "${_dnsmasq_port}"
fi fi
else else
socks_port=$(get_new_port $(expr $socks_port + 1)) socks_port=$(get_new_port $(expr $socks_port + 1))
eval node_${tcp_node}_socks_port=$socks_port set_cache_var "node_${tcp_node}_socks_port" "${socks_port}"
redir_port=$(get_new_port $(expr $redir_port + 1)) redir_port=$(get_new_port $(expr $redir_port + 1))
eval node_${tcp_node}_redir_port=$redir_port set_cache_var "node_${tcp_node}_redir_port" "${redir_port}"
tcp_port=$redir_port tcp_port=$redir_port
local type=$(echo $(config_n_get $tcp_node type) | tr 'A-Z' 'a-z') local type=$(echo $(config_n_get $tcp_node type) | tr 'A-Z' 'a-z')
@ -1835,7 +1878,7 @@ acl_app() {
[ "$dns_mode" = "xray" ] && [ "$v2ray_dns_mode" = "tcp+doh" ] && remote_dns_doh=${remote_dns_doh:-https://1.1.1.1/dns-query} [ "$dns_mode" = "xray" ] && [ "$v2ray_dns_mode" = "tcp+doh" ] && remote_dns_doh=${remote_dns_doh:-https://1.1.1.1/dns-query}
_extra_param="dns_listen_port=${_dns_port} remote_dns_protocol=${v2ray_dns_mode} remote_dns_tcp_server=${remote_dns} remote_dns_doh=${remote_dns_doh} remote_dns_query_strategy=${DNS_QUERY_STRATEGY} dns_client_ip=${dns_client_ip} dns_query_strategy=${DNS_QUERY_STRATEGY}" _extra_param="dns_listen_port=${_dns_port} remote_dns_protocol=${v2ray_dns_mode} remote_dns_tcp_server=${remote_dns} remote_dns_doh=${remote_dns_doh} remote_dns_query_strategy=${DNS_QUERY_STRATEGY} dns_client_ip=${dns_client_ip} dns_query_strategy=${DNS_QUERY_STRATEGY}"
fi fi
[ "$udp_node" != "nil" ] && ([ "$udp_node" = "tcp" ] || [ "$udp_node" = "$tcp_node" ]) && { [ -n "$udp_node" ] && ([ "$udp_node" = "tcp" ] || [ "$udp_node" = "$tcp_node" ]) && {
config_file=$(echo $config_file | sed "s/TCP_/TCP_UDP_/g") config_file=$(echo $config_file | sed "s/TCP_/TCP_UDP_/g")
_extra_param="${_extra_param} udp_redir_port=$redir_port" _extra_param="${_extra_param} udp_redir_port=$redir_port"
} }
@ -1852,41 +1895,44 @@ acl_app() {
run_dns ${_dns_port} run_dns ${_dns_port}
fi fi
set_cache_var "ACL_${sid}_tcp_node" "${tcp_node}" set_cache_var "ACL_${sid}_tcp_node" "${tcp_node}"
set_cache_var "ACL_${sid}_tcp_redir_port" "${redir_port}"
fi
} }
fi fi
set_cache_var "ACL_${sid}_tcp_port" "${tcp_port}"
} }
[ "$udp_node" != "nil" ] && { [ -n "$udp_node" ] && {
[ "$udp_node" = "tcp" ] && udp_node=$tcp_node
if [ "$udp_node" = "default" ]; then if [ "$udp_node" = "default" ]; then
if [ "$TCP_UDP" = "0" ] && [ "$UDP_NODE" = "nil" ]; then local GLOBAL_UDP_NODE=$(get_cache_var "ACL_GLOBAL_UDP_node")
udp_node="nil" [ -n "${GLOBAL_UDP_NODE}" ] && GLOBAL_UDP_redir_port=$(get_cache_var "ACL_GLOBAL_UDP_redir_port")
unset udp_port if [ -n "${GLOBAL_UDP_NODE}" ]; then
elif [ "$TCP_UDP" = "1" ] && [ "$udp_node" = "nil" ]; then set_cache_var "ACL_${sid}_udp_node" "${GLOBAL_UDP_NODE}"
udp_node=$TCP_NODE set_cache_var "ACL_${sid}_udp_redir_port" "${GLOBAL_UDP_redir_port}"
udp_port=$TCP_REDIR_PORT set_cache_var "ACL_${sid}_udp_default" "1"
else else
udp_node=$UDP_NODE echolog " - 全局节点未启用,跳过【${remarks}"
udp_port=$UDP_REDIR_PORT
fi fi
elif [ "$udp_node" = "$tcp_node" ]; then elif [ "$udp_node" = "tcp" ]; then
udp_node=$tcp_node udp_node=$(get_cache_var "ACL_${sid}_tcp_node")
udp_port=$tcp_port udp_port=$(get_cache_var "ACL_${sid}_tcp_port")
set_cache_var "ACL_${sid}_udp_node" "${udp_node}"
set_cache_var "ACL_${sid}_udp_redir_port" "${udp_port}"
else else
[ "$(config_get_type $udp_node nil)" = "nodes" ] && { [ "$(config_get_type $udp_node)" = "nodes" ] && {
if [ "$udp_node" = "$UDP_NODE" ]; then if [ -n "${GLOBAL_UDP_NODE}" ] && [ "$udp_node" = "${GLOBAL_UDP_NODE}" ]; then
udp_port=$UDP_REDIR_PORT set_cache_var "ACL_${sid}_udp_node" "${GLOBAL_UDP_NODE}"
set_cache_var "ACL_${sid}_udp_redir_port" "${GLOBAL_UDP_redir_port}"
set_cache_var "ACL_${sid}_udp_default" "1"
else else
_redir_port=$(eval echo \${node_${udp_node}_redir_port}) _redir_port=$(get_cache_var "node_${udp_node}_redir_port")
_socks_port=$(eval echo \${node_${udp_node}_socks_port}) _socks_port=$(get_cache_var "node_${udp_node}_socks_port")
if [ -n "${_socks_port}" ] && [ -n "${_redir_port}" ]; then if [ -n "${_socks_port}" ] && [ -n "${_redir_port}" ]; then
socks_port=${_socks_port} socks_port=${_socks_port}
udp_port=${_redir_port} udp_port=${_redir_port}
else else
socks_port=$(get_new_port $(expr $socks_port + 1)) socks_port=$(get_new_port $(expr $socks_port + 1))
eval node_${udp_node}_socks_port=$socks_port set_cache_var "node_${udp_node}_socks_port" "${socks_port}"
redir_port=$(get_new_port $(expr $redir_port + 1)) redir_port=$(get_new_port $(expr $redir_port + 1))
eval node_${udp_node}_redir_port=$redir_port set_cache_var "node_${udp_node}_redir_port" "${redir_port}"
udp_port=$redir_port udp_port=$redir_port
local type=$(echo $(config_n_get $udp_node type) | tr 'A-Z' 'a-z') local type=$(echo $(config_n_get $udp_node type) | tr 'A-Z' 'a-z')
@ -1904,12 +1950,12 @@ acl_app() {
fi fi
fi fi
set_cache_var "ACL_${sid}_udp_node" "${udp_node}" set_cache_var "ACL_${sid}_udp_node" "${udp_node}"
set_cache_var "ACL_${sid}_udp_redir_port" "${redir_port}"
fi fi
} }
fi fi
set_cache_var "ACL_${sid}_udp_port" "${udp_port}"
} }
unset enabled sid remarks sources interface use_global_config tcp_node udp_node use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode filter_proxy_ipv6 dns_mode remote_dns v2ray_dns_mode remote_dns_doh dns_client_ip unset enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports use_global_config tcp_node udp_node use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode filter_proxy_ipv6 dns_mode remote_dns v2ray_dns_mode remote_dns_doh dns_client_ip
unset _ip _mac _iprange _ipset _ip_or_mac source_list tcp_port udp_port config_file _extra_param unset _ip _mac _iprange _ipset _ip_or_mac source_list tcp_port udp_port config_file _extra_param
unset _china_ng_listen _chinadns_local_dns _direct_dns_mode chinadns_ng_default_tag dnsmasq_filter_proxy_ipv6 unset _china_ng_listen _chinadns_local_dns _direct_dns_mode chinadns_ng_default_tag dnsmasq_filter_proxy_ipv6
done done
@ -2013,9 +2059,9 @@ stop() {
ENABLED=$(config_t_get global enabled 0) ENABLED=$(config_t_get global enabled 0)
SOCKS_ENABLED=$(config_t_get global socks_enabled 0) SOCKS_ENABLED=$(config_t_get global socks_enabled 0)
TCP_REDIR_PORT=1041 TCP_REDIR_PORT=1041
TCP_NODE=$(config_t_get global tcp_node nil) TCP_NODE=$(config_t_get global tcp_node)
UDP_REDIR_PORT=1051 UDP_REDIR_PORT=1051
UDP_NODE=$(config_t_get global udp_node nil) UDP_NODE=$(config_t_get global udp_node)
TCP_UDP=0 TCP_UDP=0
if [ "$UDP_NODE" == "tcp" ]; then if [ "$UDP_NODE" == "tcp" ]; then
UDP_NODE=$TCP_NODE UDP_NODE=$TCP_NODE
@ -2024,8 +2070,8 @@ elif [ "$UDP_NODE" == "$TCP_NODE" ]; then
TCP_UDP=1 TCP_UDP=1
fi fi
[ "$ENABLED" == 1 ] && { [ "$ENABLED" == 1 ] && {
[ "$TCP_NODE" != "nil" ] && [ "$(config_get_type $TCP_NODE nil)" != "nil" ] && ENABLED_DEFAULT_ACL=1 [ -n "$TCP_NODE" ] && [ "$(config_get_type $TCP_NODE)" == "nodes" ] && ENABLED_DEFAULT_ACL=1
[ "$UDP_NODE" != "nil" ] && [ "$(config_get_type $UDP_NODE nil)" != "nil" ] && ENABLED_DEFAULT_ACL=1 [ -n "$UDP_NODE" ] && [ "$(config_get_type $UDP_NODE)" == "nodes" ] && ENABLED_DEFAULT_ACL=1
} }
ENABLED_ACLS=$(config_t_get global acl_enable 0) ENABLED_ACLS=$(config_t_get global acl_enable 0)
[ "$ENABLED_ACLS" == 1 ] && { [ "$ENABLED_ACLS" == 1 ] && {

View File

@ -307,8 +307,8 @@ if uci:get(appname, TCP_NODE, "protocol") == "_shunt" then
local t = uci:get_all(appname, TCP_NODE) local t = uci:get_all(appname, TCP_NODE)
local default_node_id = t["default_node"] or "_direct" local default_node_id = t["default_node"] or "_direct"
uci:foreach(appname, "shunt_rules", function(s) uci:foreach(appname, "shunt_rules", function(s)
local _node_id = t[s[".name"]] or "nil" local _node_id = t[s[".name"]]
if _node_id ~= "nil" and _node_id ~= "_blackhole" then if _node_id and _node_id ~= "_blackhole" then
if _node_id == "_default" then if _node_id == "_default" then
_node_id = default_node_id _node_id = default_node_id
end end

View File

@ -127,8 +127,9 @@ function copy_instance(var)
if line:find("passwall") then filter = true end if line:find("passwall") then filter = true end
if line:find("ubus") then filter = true end if line:find("ubus") then filter = true end
if line:find("dhcp") then filter = true end if line:find("dhcp") then filter = true end
if line:find("server") then filter = true end if line:find("server=") == 1 then filter = true end
if line:find("port") then filter = true end if line:find("port=") == 1 then filter = true end
if line:find("address=") == 1 or (line:find("server=") == 1 and line:find("/")) then filter = nil end
if not filter then if not filter then
tinsert(conf_lines, line) tinsert(conf_lines, line)
end end
@ -498,8 +499,8 @@ function add_rule(var)
local t = uci:get_all(appname, TCP_NODE) local t = uci:get_all(appname, TCP_NODE)
local default_node_id = t["default_node"] or "_direct" local default_node_id = t["default_node"] or "_direct"
uci:foreach(appname, "shunt_rules", function(s) uci:foreach(appname, "shunt_rules", function(s)
local _node_id = t[s[".name"]] or "nil" local _node_id = t[s[".name"]]
if _node_id ~= "nil" and _node_id ~= "_blackhole" then if _node_id and _node_id ~= "_blackhole" then
if _node_id == "_default" then if _node_id == "_default" then
_node_id = default_node_id _node_id = default_node_id
end end
@ -621,8 +622,9 @@ function add_rule(var)
if line:find("passwall") then filter = true end if line:find("passwall") then filter = true end
if line:find("ubus") then filter = true end if line:find("ubus") then filter = true end
if line:find("dhcp") then filter = true end if line:find("dhcp") then filter = true end
if line:find("server") then filter = true end if line:find("server=") == 1 then filter = true end
if line:find("port") then filter = true end if line:find("port=") == 1 then filter = true end
if line:find("address=") == 1 or (line:find("server=") == 1 and line:find("/")) then filter = nil end
if not filter then if not filter then
tinsert(conf_lines, line) tinsert(conf_lines, line)
end end

View File

@ -450,8 +450,8 @@ if uci:get(appname, TCP_NODE, "protocol") == "_shunt" then
local t = uci:get_all(appname, TCP_NODE) local t = uci:get_all(appname, TCP_NODE)
local default_node_id = t["default_node"] or "_direct" local default_node_id = t["default_node"] or "_direct"
uci:foreach(appname, "shunt_rules", function(s) uci:foreach(appname, "shunt_rules", function(s)
local _node_id = t[s[".name"]] or "nil" local _node_id = t[s[".name"]]
if _node_id ~= "nil" and _node_id ~= "_blackhole" then if _node_id and _node_id ~= "_blackhole" then
if _node_id == "_default" then if _node_id == "_default" then
_node_id = default_node_id _node_id = default_node_id
end end

View File

@ -198,8 +198,6 @@ load_acl() {
udp_proxy_drop_ports=${udp_proxy_drop_ports:-default} udp_proxy_drop_ports=${udp_proxy_drop_ports:-default}
tcp_redir_ports=${tcp_redir_ports:-default} tcp_redir_ports=${tcp_redir_ports:-default}
udp_redir_ports=${udp_redir_ports:-default} udp_redir_ports=${udp_redir_ports:-default}
tcp_node=${tcp_node:-nil}
udp_node=${udp_node:-nil}
use_direct_list=${use_direct_list:-1} use_direct_list=${use_direct_list:-1}
use_proxy_list=${use_proxy_list:-1} use_proxy_list=${use_proxy_list:-1}
use_block_list=${use_block_list:-1} use_block_list=${use_block_list:-1}
@ -215,25 +213,17 @@ load_acl() {
[ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS [ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS
[ -n "$(get_cache_var "ACL_${sid}_tcp_node")" ] && tcp_node=$(get_cache_var "ACL_${sid}_tcp_node") [ -n "$(get_cache_var "ACL_${sid}_tcp_node")" ] && tcp_node=$(get_cache_var "ACL_${sid}_tcp_node")
[ -n "$(get_cache_var "ACL_${sid}_tcp_redir_port")" ] && tcp_port=$(get_cache_var "ACL_${sid}_tcp_redir_port")
[ -n "$(get_cache_var "ACL_${sid}_udp_node")" ] && udp_node=$(get_cache_var "ACL_${sid}_udp_node") [ -n "$(get_cache_var "ACL_${sid}_udp_node")" ] && udp_node=$(get_cache_var "ACL_${sid}_udp_node")
[ -n "$(get_cache_var "ACL_${sid}_tcp_port")" ] && tcp_port=$(get_cache_var "ACL_${sid}_tcp_port") [ -n "$(get_cache_var "ACL_${sid}_udp_redir_port")" ] && udp_port=$(get_cache_var "ACL_${sid}_udp_redir_port")
[ -n "$(get_cache_var "ACL_${sid}_udp_port")" ] && udp_port=$(get_cache_var "ACL_${sid}_udp_port")
[ -n "$(get_cache_var "ACL_${sid}_dns_port")" ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port") [ -n "$(get_cache_var "ACL_${sid}_dns_port")" ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port")
[ -n "$tcp_node" ] && tcp_node_remark=$(config_n_get $tcp_node remarks)
[ -n "$udp_node" ] && udp_node_remark=$(config_n_get $udp_node remarks)
use_shunt_tcp=0 use_shunt_tcp=0
use_shunt_udp=0 use_shunt_udp=0
[ "$tcp_node" != "nil" ] && { [ -n "$tcp_node" ] && [ "$(config_n_get $tcp_node protocol)" = "_shunt" ] && use_shunt_tcp=1
tcp_node_remark=$(config_n_get $tcp_node remarks) [ -n "$udp_node" ] && [ "$(config_n_get $udp_node protocol)" = "_shunt" ] && use_shunt_udp=1
[ "$(config_n_get $tcp_node protocol)" = "_shunt" ] && use_shunt_tcp=1
}
[ "$udp_node" != "nil" ] && {
udp_node_remark=$(config_n_get $udp_node remarks)
[ "$(config_n_get $udp_node protocol)" = "_shunt" ] && use_shunt_udp=1
}
[ "$udp_node" == "tcp" ] && {
udp_node_remark=$tcp_node_remark
use_shunt_udp=$use_shunt_tcp
}
[ "${use_global_config}" = "1" ] && { [ "${use_global_config}" = "1" ] && {
tcp_node_remark=$(config_n_get $TCP_NODE remarks) tcp_node_remark=$(config_n_get $TCP_NODE remarks)
@ -503,7 +493,7 @@ load_acl() {
local DNS_REDIRECT local DNS_REDIRECT
[ $(config_t_get global dns_redirect "1") = "1" ] && DNS_REDIRECT=53 [ $(config_t_get global dns_redirect "1") = "1" ] && DNS_REDIRECT=53
if ([ "$TCP_NODE" != "nil" ] && [ -n "${TCP_PROXY_MODE}" ]) || ([ "$UDP_NODE" != "nil" ] && [ -n "${UDP_PROXY_MODE}" ]); then if ([ -n "$TCP_NODE" ] && [ -n "${TCP_PROXY_MODE}" ]) || ([ -n "$UDP_NODE" ] && [ -n "${UDP_PROXY_MODE}" ]); then
[ -n "${DNS_REDIRECT_PORT}" ] && DNS_REDIRECT=${DNS_REDIRECT_PORT} [ -n "${DNS_REDIRECT_PORT}" ] && DNS_REDIRECT=${DNS_REDIRECT_PORT}
else else
[ -n "${DIRECT_DNSMASQ_PORT}" ] && DNS_REDIRECT=${DIRECT_DNSMASQ_PORT} [ -n "${DIRECT_DNSMASQ_PORT}" ] && DNS_REDIRECT=${DIRECT_DNSMASQ_PORT}
@ -566,7 +556,7 @@ load_acl() {
# 加载TCP默认代理模式 # 加载TCP默认代理模式
if [ -n "${TCP_PROXY_MODE}" ]; then if [ -n "${TCP_PROXY_MODE}" ]; then
[ "$TCP_NODE" != "nil" ] && { [ -n "$TCP_NODE" ] && {
msg2="${msg}使用 TCP 节点[$(config_n_get $TCP_NODE remarks)]" msg2="${msg}使用 TCP 节点[$(config_n_get $TCP_NODE remarks)]"
if [ -n "${is_tproxy}" ]; then if [ -n "${is_tproxy}" ]; then
msg2="${msg2}(TPROXY:${TCP_REDIR_PORT})" msg2="${msg2}(TPROXY:${TCP_REDIR_PORT})"
@ -619,7 +609,7 @@ load_acl() {
# 加载UDP默认代理模式 # 加载UDP默认代理模式
if [ -n "${UDP_PROXY_MODE}" ]; then if [ -n "${UDP_PROXY_MODE}" ]; then
[ "$UDP_NODE" != "nil" -o "$TCP_UDP" = "1" ] && { [ -n "$UDP_NODE" -o "$TCP_UDP" = "1" ] && {
msg2="${msg}使用 UDP 节点[$(config_n_get $UDP_NODE remarks)](TPROXY:${UDP_REDIR_PORT})" msg2="${msg}使用 UDP 节点[$(config_n_get $UDP_NODE remarks)](TPROXY:${UDP_REDIR_PORT})"
$ipt_m -A PSW $(comment "默认") -p udp -d $FAKE_IP -j PSW_RULE $ipt_m -A PSW $(comment "默认") -p udp -d $FAKE_IP -j PSW_RULE
@ -686,7 +676,7 @@ filter_server_port() {
filter_node() { filter_node() {
local node=${1} local node=${1}
local stream=${2} local stream=${2}
if [ -n "$node" ] && [ "$node" != "nil" ]; then if [ -n "$node" ]; then
local address=$(config_n_get $node address) local address=$(config_n_get $node address)
local port=$(config_n_get $node port) local port=$(config_n_get $node port)
[ -z "$address" ] && [ -z "$port" ] && { [ -z "$address" ] && [ -z "$port" ] && {
@ -736,12 +726,12 @@ add_firewall_rule() {
local USE_PROXY_LIST_ALL=${USE_PROXY_LIST} local USE_PROXY_LIST_ALL=${USE_PROXY_LIST}
local USE_DIRECT_LIST_ALL=${USE_DIRECT_LIST} local USE_DIRECT_LIST_ALL=${USE_DIRECT_LIST}
local USE_BLOCK_LIST_ALL=${USE_BLOCK_LIST} local USE_BLOCK_LIST_ALL=${USE_BLOCK_LIST}
local _TCP_NODE=$(config_t_get global tcp_node nil) local _TCP_NODE=$(config_t_get global tcp_node)
local _UDP_NODE=$(config_t_get global udp_node nil) local _UDP_NODE=$(config_t_get global udp_node)
local USE_GEOVIEW=$(config_t_get global_rules enable_geoview) local USE_GEOVIEW=$(config_t_get global_rules enable_geoview)
[ "$_TCP_NODE" != "nil" ] && [ "$(config_n_get $_TCP_NODE protocol)" = "_shunt" ] && USE_SHUNT_TCP=1 && USE_SHUNT_NODE=1 [ -n "$_TCP_NODE" ] && [ "$(config_n_get $_TCP_NODE protocol)" = "_shunt" ] && USE_SHUNT_TCP=1 && USE_SHUNT_NODE=1
[ "$_UDP_NODE" != "nil" ] && [ "$(config_n_get $_UDP_NODE protocol)" = "_shunt" ] && USE_SHUNT_UDP=1 && USE_SHUNT_NODE=1 [ -n "$_UDP_NODE" ] && [ "$(config_n_get $_UDP_NODE protocol)" = "_shunt" ] && USE_SHUNT_UDP=1 && USE_SHUNT_NODE=1
[ "$_UDP_NODE" = "tcp" ] && USE_SHUNT_UDP=$USE_SHUNT_TCP [ "$_UDP_NODE" = "tcp" ] && USE_SHUNT_UDP=$USE_SHUNT_TCP
for acl_section in $(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do for acl_section in $(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do
@ -1012,7 +1002,7 @@ add_firewall_rule() {
ip -6 rule add fwmark 1 table 100 ip -6 rule add fwmark 1 table 100
ip -6 route add local ::/0 dev lo table 100 ip -6 route add local ::/0 dev lo table 100
[ "$TCP_UDP" = "1" ] && [ "$UDP_NODE" = "nil" ] && UDP_NODE=$TCP_NODE [ "$TCP_UDP" = "1" ] && [ -z "$UDP_NODE" ] && UDP_NODE=$TCP_NODE
[ "$ENABLED_DEFAULT_ACL" == 1 ] && { [ "$ENABLED_DEFAULT_ACL" == 1 ] && {
local ipt_tmp=$ipt_n local ipt_tmp=$ipt_n
@ -1046,7 +1036,7 @@ add_firewall_rule() {
fi fi
} }
if ([ "$TCP_NODE" != "nil" ] && [ -n "${LOCALHOST_TCP_PROXY_MODE}" ]) || ([ "$UDP_NODE" != "nil" ] && [ -n "${LOCALHOST_UDP_PROXY_MODE}" ]); then if ([ -n "$TCP_NODE" ] && [ -n "${LOCALHOST_TCP_PROXY_MODE}" ]) || ([ -n "$UDP_NODE" ] && [ -n "${LOCALHOST_UDP_PROXY_MODE}" ]); then
[ -n "$DNS_REDIRECT_PORT" ] && { [ -n "$DNS_REDIRECT_PORT" ] && {
$ipt_n -A OUTPUT $(comment "PSW") -p udp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT $ipt_n -A OUTPUT $(comment "PSW") -p udp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT
$ip6t_n -A OUTPUT $(comment "PSW") -p udp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null $ip6t_n -A OUTPUT $(comment "PSW") -p udp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null
@ -1078,7 +1068,7 @@ add_firewall_rule() {
} }
# 加载路由器自身代理 TCP # 加载路由器自身代理 TCP
if [ "$TCP_NODE" != "nil" ]; then if [ -n "$TCP_NODE" ]; then
_proxy_tcp_access() { _proxy_tcp_access() {
[ -n "${2}" ] || return 0 [ -n "${2}" ] || return 0
if echo "${2}" | grep -q -v ':'; then if echo "${2}" | grep -q -v ':'; then
@ -1156,7 +1146,7 @@ add_firewall_rule() {
fi fi
# 加载路由器自身代理 UDP # 加载路由器自身代理 UDP
if [ "$UDP_NODE" != "nil" -o "$TCP_UDP" = "1" ]; then if [ -n "$UDP_NODE" -o "$TCP_UDP" = "1" ]; then
_proxy_udp_access() { _proxy_udp_access() {
[ -n "${2}" ] || return 0 [ -n "${2}" ] || return 0
if echo "${2}" | grep -q -v ':'; then if echo "${2}" | grep -q -v ':'; then

View File

@ -258,8 +258,6 @@ load_acl() {
udp_proxy_drop_ports=${udp_proxy_drop_ports:-default} udp_proxy_drop_ports=${udp_proxy_drop_ports:-default}
tcp_redir_ports=${tcp_redir_ports:-default} tcp_redir_ports=${tcp_redir_ports:-default}
udp_redir_ports=${udp_redir_ports:-default} udp_redir_ports=${udp_redir_ports:-default}
tcp_node=${tcp_node:-nil}
udp_node=${udp_node:-nil}
use_direct_list=${use_direct_list:-1} use_direct_list=${use_direct_list:-1}
use_proxy_list=${use_proxy_list:-1} use_proxy_list=${use_proxy_list:-1}
use_block_list=${use_block_list:-1} use_block_list=${use_block_list:-1}
@ -275,25 +273,17 @@ load_acl() {
[ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS [ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS
[ -n "$(get_cache_var "ACL_${sid}_tcp_node")" ] && tcp_node=$(get_cache_var "ACL_${sid}_tcp_node") [ -n "$(get_cache_var "ACL_${sid}_tcp_node")" ] && tcp_node=$(get_cache_var "ACL_${sid}_tcp_node")
[ -n "$(get_cache_var "ACL_${sid}_tcp_redir_port")" ] && tcp_port=$(get_cache_var "ACL_${sid}_tcp_redir_port")
[ -n "$(get_cache_var "ACL_${sid}_udp_node")" ] && udp_node=$(get_cache_var "ACL_${sid}_udp_node") [ -n "$(get_cache_var "ACL_${sid}_udp_node")" ] && udp_node=$(get_cache_var "ACL_${sid}_udp_node")
[ -n "$(get_cache_var "ACL_${sid}_tcp_port")" ] && tcp_port=$(get_cache_var "ACL_${sid}_tcp_port") [ -n "$(get_cache_var "ACL_${sid}_udp_redir_port")" ] && udp_port=$(get_cache_var "ACL_${sid}_udp_redir_port")
[ -n "$(get_cache_var "ACL_${sid}_udp_port")" ] && udp_port=$(get_cache_var "ACL_${sid}_udp_port")
[ -n "$(get_cache_var "ACL_${sid}_dns_port")" ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port") [ -n "$(get_cache_var "ACL_${sid}_dns_port")" ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port")
[ -n "$tcp_node" ] && tcp_node_remark=$(config_n_get $tcp_node remarks)
[ -n "$udp_node" ] && udp_node_remark=$(config_n_get $udp_node remarks)
use_shunt_tcp=0 use_shunt_tcp=0
use_shunt_udp=0 use_shunt_udp=0
[ "$tcp_node" != "nil" ] && { [ -n "$tcp_node" ] && [ "$(config_n_get $tcp_node protocol)" = "_shunt" ] && use_shunt_tcp=1
tcp_node_remark=$(config_n_get $tcp_node remarks) [ -n "$udp_node" ] && [ "$(config_n_get $udp_node protocol)" = "_shunt" ] && use_shunt_udp=1
[ "$(config_n_get $tcp_node protocol)" = "_shunt" ] && use_shunt_tcp=1
}
[ "$udp_node" != "nil" ] && {
udp_node_remark=$(config_n_get $udp_node remarks)
[ "$(config_n_get $udp_node protocol)" = "_shunt" ] && use_shunt_udp=1
}
[ "$udp_node" == "tcp" ] && {
udp_node_remark=$tcp_node_remark
use_shunt_udp=$use_shunt_tcp
}
[ "${use_global_config}" = "1" ] && { [ "${use_global_config}" = "1" ] && {
tcp_node_remark=$(config_n_get $TCP_NODE remarks) tcp_node_remark=$(config_n_get $TCP_NODE remarks)
@ -556,7 +546,7 @@ load_acl() {
local DNS_REDIRECT local DNS_REDIRECT
[ $(config_t_get global dns_redirect "1") = "1" ] && DNS_REDIRECT=53 [ $(config_t_get global dns_redirect "1") = "1" ] && DNS_REDIRECT=53
if ([ "$TCP_NODE" != "nil" ] && [ -n "${TCP_PROXY_MODE}" ]) || ([ "$UDP_NODE" != "nil" ] && [ -n "${UDP_PROXY_MODE}" ]); then if ([ -n "$TCP_NODE" ] && [ -n "${TCP_PROXY_MODE}" ]) || ([ -n "$UDP_NODE" ] && [ -n "${UDP_PROXY_MODE}" ]); then
[ -n "${DNS_REDIRECT_PORT}" ] && DNS_REDIRECT=${DNS_REDIRECT_PORT} [ -n "${DNS_REDIRECT_PORT}" ] && DNS_REDIRECT=${DNS_REDIRECT_PORT}
else else
[ -n "${DIRECT_DNSMASQ_PORT}" ] && DNS_REDIRECT=${DIRECT_DNSMASQ_PORT} [ -n "${DIRECT_DNSMASQ_PORT}" ] && DNS_REDIRECT=${DIRECT_DNSMASQ_PORT}
@ -621,7 +611,7 @@ load_acl() {
# 加载TCP默认代理模式 # 加载TCP默认代理模式
if [ -n "${TCP_PROXY_MODE}" ]; then if [ -n "${TCP_PROXY_MODE}" ]; then
[ "$TCP_NODE" != "nil" ] && { [ -n "$TCP_NODE" ] && {
msg2="${msg}使用 TCP 节点[$(config_n_get $TCP_NODE remarks)]" msg2="${msg}使用 TCP 节点[$(config_n_get $TCP_NODE remarks)]"
if [ -n "${is_tproxy}" ]; then if [ -n "${is_tproxy}" ]; then
msg2="${msg2}(TPROXY:${TCP_REDIR_PORT})" msg2="${msg2}(TPROXY:${TCP_REDIR_PORT})"
@ -679,7 +669,7 @@ load_acl() {
# 加载UDP默认代理模式 # 加载UDP默认代理模式
if [ -n "${UDP_PROXY_MODE}" ]; then if [ -n "${UDP_PROXY_MODE}" ]; then
[ "$UDP_NODE" != "nil" -o "$TCP_UDP" = "1" ] && { [ -n "$UDP_NODE" -o "$TCP_UDP" = "1" ] && {
msg2="${msg}使用 UDP 节点[$(config_n_get $UDP_NODE remarks)](TPROXY:${UDP_REDIR_PORT})" msg2="${msg}使用 UDP 节点[$(config_n_get $UDP_NODE remarks)](TPROXY:${UDP_REDIR_PORT})"
nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW_RULE comment \"默认\"" nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW_RULE comment \"默认\""
@ -753,7 +743,7 @@ filter_server_port() {
filter_node() { filter_node() {
local node=${1} local node=${1}
local stream=${2} local stream=${2}
if [ -n "$node" ] && [ "$node" != "nil" ]; then if [ -n "$node" ]; then
local address=$(config_n_get $node address) local address=$(config_n_get $node address)
local port=$(config_n_get $node port) local port=$(config_n_get $node port)
[ -z "$address" ] && [ -z "$port" ] && { [ -z "$address" ] && [ -z "$port" ] && {
@ -811,12 +801,12 @@ add_firewall_rule() {
local USE_PROXY_LIST_ALL=${USE_PROXY_LIST} local USE_PROXY_LIST_ALL=${USE_PROXY_LIST}
local USE_DIRECT_LIST_ALL=${USE_DIRECT_LIST} local USE_DIRECT_LIST_ALL=${USE_DIRECT_LIST}
local USE_BLOCK_LIST_ALL=${USE_BLOCK_LIST} local USE_BLOCK_LIST_ALL=${USE_BLOCK_LIST}
local _TCP_NODE=$(config_t_get global tcp_node nil) local _TCP_NODE=$(config_t_get global tcp_node)
local _UDP_NODE=$(config_t_get global udp_node nil) local _UDP_NODE=$(config_t_get global udp_node)
local USE_GEOVIEW=$(config_t_get global_rules enable_geoview) local USE_GEOVIEW=$(config_t_get global_rules enable_geoview)
[ "$_TCP_NODE" != "nil" ] && [ "$(config_n_get $_TCP_NODE protocol)" = "_shunt" ] && USE_SHUNT_TCP=1 && USE_SHUNT_NODE=1 [ -n "$_TCP_NODE" ] && [ "$(config_n_get $_TCP_NODE protocol)" = "_shunt" ] && USE_SHUNT_TCP=1 && USE_SHUNT_NODE=1
[ "$_UDP_NODE" != "nil" ] && [ "$(config_n_get $_UDP_NODE protocol)" = "_shunt" ] && USE_SHUNT_UDP=1 && USE_SHUNT_NODE=1 [ -n "$_UDP_NODE" ] && [ "$(config_n_get $_UDP_NODE protocol)" = "_shunt" ] && USE_SHUNT_UDP=1 && USE_SHUNT_NODE=1
[ "$_UDP_NODE" = "tcp" ] && USE_SHUNT_UDP=$USE_SHUNT_TCP [ "$_UDP_NODE" = "tcp" ] && USE_SHUNT_UDP=$USE_SHUNT_TCP
for acl_section in $(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do for acl_section in $(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do
@ -1077,7 +1067,7 @@ add_firewall_rule() {
ip -6 route add local ::/0 dev lo table 100 ip -6 route add local ::/0 dev lo table 100
} }
[ "$TCP_UDP" = "1" ] && [ "$UDP_NODE" = "nil" ] && UDP_NODE=$TCP_NODE [ "$TCP_UDP" = "1" ] && [ -z "$UDP_NODE" ] && UDP_NODE=$TCP_NODE
[ "$ENABLED_DEFAULT_ACL" == 1 ] && { [ "$ENABLED_DEFAULT_ACL" == 1 ] && {
msg="【路由器本机】," msg="【路由器本机】,"
@ -1104,7 +1094,7 @@ add_firewall_rule() {
fi fi
} }
if ([ "$TCP_NODE" != "nil" ] && [ -n "${LOCALHOST_TCP_PROXY_MODE}" ]) || ([ "$UDP_NODE" != "nil" ] && [ -n "${LOCALHOST_UDP_PROXY_MODE}" ]); then if ([ -n "$TCP_NODE" ] && [ -n "${LOCALHOST_TCP_PROXY_MODE}" ]) || ([ -n "$UDP_NODE" ] && [ -n "${LOCALHOST_UDP_PROXY_MODE}" ]); then
[ -n "$DNS_REDIRECT_PORT" ] && { [ -n "$DNS_REDIRECT_PORT" ] && {
nft "add rule $NFTABLE_NAME nat_output ip protocol udp oif lo udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW\"" nft "add rule $NFTABLE_NAME nat_output ip protocol udp oif lo udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW\""
nft "add rule $NFTABLE_NAME nat_output ip protocol tcp oif lo tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW\"" nft "add rule $NFTABLE_NAME nat_output ip protocol tcp oif lo tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW\""
@ -1136,7 +1126,7 @@ add_firewall_rule() {
} }
# 加载路由器自身代理 TCP # 加载路由器自身代理 TCP
if [ "$TCP_NODE" != "nil" ]; then if [ -n "$TCP_NODE" ]; then
_proxy_tcp_access() { _proxy_tcp_access() {
[ -n "${2}" ] || return 0 [ -n "${2}" ] || return 0
if echo "${2}" | grep -q -v ':'; then if echo "${2}" | grep -q -v ':'; then
@ -1219,7 +1209,7 @@ add_firewall_rule() {
fi fi
# 加载路由器自身代理 UDP # 加载路由器自身代理 UDP
if [ "$UDP_NODE" != "nil" -o "$TCP_UDP" = "1" ]; then if [ -n "$UDP_NODE" -o "$TCP_UDP" = "1" ]; then
_proxy_udp_access() { _proxy_udp_access() {
[ -n "${2}" ] || return 0 [ -n "${2}" ] || return 0
if echo "${2}" | grep -q -v ':'; then if echo "${2}" | grep -q -v ':'; then

View File

@ -61,8 +61,8 @@ test_proxy() {
test_node() { test_node() {
local node_id=$1 local node_id=$1
local _type=$(echo $(config_n_get ${node_id} type nil) | tr 'A-Z' 'a-z') local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z')
[ "${_type}" != "nil" ] && { [ -n "${_type}" ] && {
local _tmp_port=$(/usr/share/${CONFIG}/app.sh get_new_port 61080 tcp,udp) local _tmp_port=$(/usr/share/${CONFIG}/app.sh get_new_port 61080 tcp,udp)
/usr/share/${CONFIG}/app.sh run_socks flag="test_node_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=test_node_${node_id}.json /usr/share/${CONFIG}/app.sh run_socks flag="test_node_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=test_node_${node_id}.json
local curlx="socks5h://127.0.0.1:${_tmp_port}" local curlx="socks5h://127.0.0.1:${_tmp_port}"
@ -101,7 +101,7 @@ test_auto_switch() {
fi fi
#检测主节点是否能使用 #检测主节点是否能使用
if [ "$restore_switch" == "1" ] && [ "$main_node" != "nil" ] && [ "$now_node" != "$main_node" ]; then if [ "$restore_switch" == "1" ] && [ -n "$main_node" ] && [ "$now_node" != "$main_node" ]; then
test_node ${main_node} test_node ${main_node}
[ $? -eq 0 ] && { [ $? -eq 0 ] && {
#主节点正常,切换到主节点 #主节点正常,切换到主节点
@ -159,7 +159,7 @@ start() {
LOCK_FILE=${LOCK_FILE_DIR}/${CONFIG}_socks_auto_switch_${id}.lock LOCK_FILE=${LOCK_FILE_DIR}/${CONFIG}_socks_auto_switch_${id}.lock
LOG_EVENT_FILTER=$(uci -q get "${CONFIG}.global[0].log_event_filter" 2>/dev/null) LOG_EVENT_FILTER=$(uci -q get "${CONFIG}.global[0].log_event_filter" 2>/dev/null)
LOG_EVENT_CMD=$(uci -q get "${CONFIG}.global[0].log_event_cmd" 2>/dev/null) LOG_EVENT_CMD=$(uci -q get "${CONFIG}.global[0].log_event_cmd" 2>/dev/null)
main_node=$(config_n_get $id node nil) main_node=$(config_n_get $id node)
socks_port=$(config_n_get $id port 0) socks_port=$(config_n_get $id port 0)
delay=$(config_n_get $id autoswitch_testing_time 30) delay=$(config_n_get $id autoswitch_testing_time 30)
sleep 5s sleep 5s
@ -167,8 +167,8 @@ start() {
retry_num=$(config_n_get $id autoswitch_retry_num 1) retry_num=$(config_n_get $id autoswitch_retry_num 1)
restore_switch=$(config_n_get $id autoswitch_restore_switch 0) 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") probe_url=$(config_n_get $id autoswitch_probe_url "https://www.google.com/generate_204")
backup_node=$(config_n_get $id autoswitch_backup_node nil) backup_node=$(config_n_get $id autoswitch_backup_node)
while [ -n "$backup_node" -a "$backup_node" != "nil" ]; do while [ -n "$backup_node" ]; do
[ -f "$LOCK_FILE" ] && { [ -f "$LOCK_FILE" ] && {
sleep 6s sleep 6s
continue continue

View File

@ -264,7 +264,7 @@ do
currentNode = _node_id and uci:get_all(appname, _node_id) or nil, currentNode = _node_id and uci:get_all(appname, _node_id) or nil,
remarks = "分流" .. e.remarks .. "节点", remarks = "分流" .. e.remarks .. "节点",
set = function(o, server) set = function(o, server)
if not server then server = "nil" end if not server then server = "" end
uci:set(appname, node_id, e[".name"], server) uci:set(appname, node_id, e[".name"], server)
o.newNodeId = server o.newNodeId = server
end end
@ -1263,10 +1263,10 @@ local function truncate_nodes(add_from)
if config.currentNode and config.currentNode.add_mode == "2" then if config.currentNode and config.currentNode.add_mode == "2" then
if add_from then if add_from then
if config.currentNode.add_from and config.currentNode.add_from == add_from then if config.currentNode.add_from and config.currentNode.add_from == add_from then
config.set(config, "nil") config.set(config, "")
end end
else else
config.set(config, "nil") config.set(config, "")
end end
if config.id then if config.id then
uci:delete(appname, config.id) uci:delete(appname, config.id)
@ -1400,7 +1400,7 @@ local function select_node(nodes, config)
config.set(config, server) config.set(config, server)
end end
else else
config.set(config, "nil") config.set(config, "")
end end
end end

View File

@ -30,6 +30,33 @@ do
if [ "$CFG_UPDATE_INT" -ne 0 ]; then if [ "$CFG_UPDATE_INT" -ne 0 ]; then
stop_week_mode=$(config_t_get global_delay stop_week_mode)
stop_interval_mode=$(config_t_get global_delay stop_interval_mode)
stop_interval_mode=$(expr "$stop_interval_mode" \* 60)
if [ -n "$stop_week_mode" ]; then
[ "$stop_week_mode" = "8" ] && {
[ "$(expr "$CFG_UPDATE_INT" % "$stop_interval_mode")" -eq 0 ] && /etc/init.d/$CONFIG stop > /dev/null 2>&1 &
}
fi
start_week_mode=$(config_t_get global_delay start_week_mode)
start_interval_mode=$(config_t_get global_delay start_interval_mode)
start_interval_mode=$(expr "$start_interval_mode" \* 60)
if [ -n "$start_week_mode" ]; then
[ "$start_week_mode" = "8" ] && {
[ "$(expr "$CFG_UPDATE_INT" % "$start_interval_mode")" -eq 0 ] && /etc/init.d/$CONFIG start > /dev/null 2>&1 &
}
fi
restart_week_mode=$(config_t_get global_delay restart_week_mode)
restart_interval_mode=$(config_t_get global_delay restart_interval_mode)
restart_interval_mode=$(expr "$restart_interval_mode" \* 60)
if [ -n "$restart_week_mode" ]; then
[ "$restart_week_mode" = "8" ] && {
[ "$(expr "$CFG_UPDATE_INT" % "$restart_interval_mode")" -eq 0 ] && /etc/init.d/$CONFIG restart > /dev/null 2>&1 &
}
fi
autoupdate=$(config_t_get global_rules auto_update) autoupdate=$(config_t_get global_rules auto_update)
weekupdate=$(config_t_get global_rules week_update) weekupdate=$(config_t_get global_rules week_update)
hourupdate=$(config_t_get global_rules interval_update) hourupdate=$(config_t_get global_rules interval_update)

View File

@ -56,8 +56,8 @@ test_proxy() {
url_test_node() { url_test_node() {
result=0 result=0
local node_id=$1 local node_id=$1
local _type=$(echo $(config_n_get ${node_id} type nil) | tr 'A-Z' 'a-z') local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z')
[ "${_type}" != "nil" ] && { [ -n "${_type}" ] && {
if [ "${_type}" == "socks" ]; then if [ "${_type}" == "socks" ]; then
local _address=$(config_n_get ${node_id} address) local _address=$(config_n_get ${node_id} address)
local _port=$(config_n_get ${node_id} port) local _port=$(config_n_get ${node_id} port)
@ -85,8 +85,8 @@ url_test_node() {
test_node() { test_node() {
local node_id=$1 local node_id=$1
local _type=$(echo $(config_n_get ${node_id} type nil) | tr 'A-Z' 'a-z') local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z')
[ "${_type}" != "nil" ] && { [ -n "${_type}" ] && {
if [ "${_type}" == "socks" ]; then if [ "${_type}" == "socks" ]; then
local _address=$(config_n_get ${node_id} address) local _address=$(config_n_get ${node_id} address)
local _port=$(config_n_get ${node_id} port) local _port=$(config_n_get ${node_id} port)

View File

@ -20,7 +20,7 @@ index 2b72468..15c6437 100644
define Package/$(PKG_NAME)/postrm define Package/$(PKG_NAME)/postrm
diff --git a/luci-app-passwall/luasrc/controller/passwall.lua b/luci-app-passwall/luasrc/controller/passwall.lua diff --git a/luci-app-passwall/luasrc/controller/passwall.lua b/luci-app-passwall/luasrc/controller/passwall.lua
index 33c5319..6ddcdfd 100644 index 6851861..669a612 100644
--- a/luci-app-passwall/luasrc/controller/passwall.lua --- a/luci-app-passwall/luasrc/controller/passwall.lua
+++ b/luci-app-passwall/luasrc/controller/passwall.lua +++ b/luci-app-passwall/luasrc/controller/passwall.lua
@@ -279,7 +279,7 @@ function connect_status() @@ -279,7 +279,7 @@ function connect_status()
@ -33,10 +33,10 @@ index 33c5319..6ddcdfd 100644
if code ~= 0 then if code ~= 0 then
local use_time = luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $2}'") local use_time = luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $2}'")
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua 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 488cd50..541167f 100644 index 7ea652a..2b4c853 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
@@ -467,6 +467,12 @@ o:value("9.9.9.9", "9.9.9.9 (Quad9)") @@ -465,6 +465,12 @@ o:value("9.9.9.9", "9.9.9.9 (Quad9)")
o:value("149.112.112.112", "149.112.112.112 (Quad9)") o:value("149.112.112.112", "149.112.112.112 (Quad9)")
o:value("208.67.220.220", "208.67.220.220 (OpenDNS)") o:value("208.67.220.220", "208.67.220.220 (OpenDNS)")
o:value("208.67.222.222", "208.67.222.222 (OpenDNS)") o:value("208.67.222.222", "208.67.222.222 (OpenDNS)")
@ -133,12 +133,12 @@ index e8d76ec..a872950 100644
<div class="pure-u-1-3"> <div class="pure-u-1-3">
<div class="img-con"> <div class="img-con">
diff --git a/luci-app-passwall/root/usr/share/passwall/0_default_config b/luci-app-passwall/root/usr/share/passwall/0_default_config diff --git a/luci-app-passwall/root/usr/share/passwall/0_default_config b/luci-app-passwall/root/usr/share/passwall/0_default_config
index 8348217..19b16b7 100644 index 551c824..2a6a814 100644
--- a/luci-app-passwall/root/usr/share/passwall/0_default_config --- a/luci-app-passwall/root/usr/share/passwall/0_default_config
+++ b/luci-app-passwall/root/usr/share/passwall/0_default_config +++ b/luci-app-passwall/root/usr/share/passwall/0_default_config
@@ -34,7 +34,7 @@ config global_haproxy @@ -31,7 +31,7 @@ config global_haproxy
config global_delay config global_delay
option auto_on '0'
option start_daemon '1' option start_daemon '1'
- option start_delay '60' - option start_delay '60'
+ option start_delay '15' + option start_delay '15'