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

View File

@ -52,7 +52,7 @@ o.rmempty = false
---- Remarks
o = s:option(Value, "remarks", translate("Remarks"))
o.default = arg[1]
o.rmempty = true
o.rmempty = false
o = s:option(ListValue, "interface", translate("Source Interface"))
o:value("", translate("All"))
@ -148,97 +148,117 @@ sources.write = dynamicList_write
---- 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.default = "default"
o:value("", translate("Use global config") .. "(" .. TCP_NO_REDIR_PORTS .. ")")
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.validate = port_validate
---- 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"),
"<font color='red'>" .. translate(
"Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") ..
"</font>")
o.default = "default"
"<font color='red'>" ..
translate("Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") ..
"</font>")
o:value("", translate("Use global config") .. "(" .. UDP_NO_REDIR_PORTS .. ")")
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.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.default = "0"
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>")
tcp_node.default = ""
tcp_node:value("", translate("Close"))
tcp_node:depends("use_global_config", false)
o = s:option(ListValue, "tcp_node", "<a style='color: red'>" .. translate("TCP Node") .. "</a>")
o.default = ""
o:depends({ _hide_node_option = false, use_global_config = false })
udp_node = s:option(ListValue, "udp_node", "<a style='color: red'>" .. translate("UDP Node") .. "</a>")
udp_node.default = ""
udp_node:value("", translate("Close"))
udp_node:value("tcp", translate("Same as the tcp node"))
udp_node:depends({ tcp_node = "", ['!reverse'] = true })
o = s:option(DummyValue, "_tcp_node_bool", "")
o.template = "passwall/cbi/hidevalue"
o.value = "1"
o: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
tcp_node:value(v.id, v["remark"])
udp_node:value(v.id, v["remark"])
s.fields["tcp_node"]:value(v.id, v["remark"])
s.fields["udp_node"]:value(v.id, v["remark"])
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
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.default = "default"
o:value("", translate("Use global config") .. "(" .. TCP_PROXY_DROP_PORTS .. ")")
o:value("disable", translate("No patterns are used"))
o:value("default", translate("Use global config") .. "(" .. TCP_PROXY_DROP_PORTS .. ")")
o.validate = port_validate
o:depends({ use_global_config = true })
o:depends({ _tcp_node_bool = "1" })
---- 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.default = "default"
o:value("", translate("Use global config") .. "(" .. UDP_PROXY_DROP_PORTS .. ")")
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.validate = port_validate
o:depends({ use_global_config = true })
o:depends({ _tcp_node_bool = "1" })
---- 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.default = "default"
o:value("default", translate("Use global config") .. "(" .. TCP_REDIR_PORTS .. ")")
o:value("", translate("Use global config") .. "(" .. TCP_REDIR_PORTS .. ")")
o:value("1:65535", translate("All"))
o:value("80,443", "80,443")
o:value("80:65535", "80 " .. translate("or more"))
o:value("1:443", "443 " .. translate("or less"))
o.validate = port_validate
o:depends({ use_global_config = true })
o:depends({ _tcp_node_bool = "1" })
---- 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.default = "default"
o:value("default", translate("Use global config") .. "(" .. UDP_REDIR_PORTS .. ")")
o:value("", translate("Use global config") .. "(" .. UDP_REDIR_PORTS .. ")")
o:value("1:65535", translate("All"))
o:value("53", "53")
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.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.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.default = "1"
o:depends({ tcp_node = "", ['!reverse'] = true })
o:depends({ _tcp_node_bool = "1" })
if has_gfwlist then
o = s:option(Flag, "use_gfw_list", translatef("Use %s", translate("GFW List")))
o.default = "1"
o:depends({ tcp_node = "", ['!reverse'] = true })
o:depends({ _tcp_node_bool = "1" })
end
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("proxy", translate("Proxy"))
o.default = "direct"
o:depends({ tcp_node = "", ['!reverse'] = true })
o:depends({ _tcp_node_bool = "1" })
end
o = s:option(ListValue, "tcp_proxy_mode", "TCP " .. translate("Proxy Mode"))
o:value("disable", translate("No 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:value("disable", translate("No 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.template = appname .. "/global/proxy"
o:depends({ tcp_node = "", ['!reverse'] = true })
o:depends({ _tcp_node_bool = "1" })
---- DNS
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("chinadns-ng", translate("ChinaDNS-NG (recommended)"))
o = s:option(Flag, "filter_proxy_ipv6", translate("Filter Proxy Host IPv6"), translate("Experimental feature."))
o.default = "0"
o:depends({ tcp_node = "", ['!reverse'] = true })
o:depends({ _tcp_node_bool = "1" })
---- DNS Forward 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
o:value("dns2socks", "dns2socks")
end

View File

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

View File

@ -61,15 +61,15 @@ function s.remove(e, t)
end
end)
TypedSection.remove(e, t)
local new_node = "nil"
local new_node = ""
local node0 = m:get("@nodes[0]") or nil
if node0 then
new_node = node0[".name"]
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)
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)
end
end

View File

@ -17,44 +17,44 @@ s = m:section(TypedSection, "global_delay", translate("Delay Settings"))
s.anonymous = true
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
o = s:option(Flag, "start_daemon", translate("Open and close Daemon"))
o.default = 1
o.rmempty = false
--[[
---- Open and close automatically
o = s:option(Flag, "auto_on", translate("Open and close automatically"))
o.default = 0
o.rmempty = false
---- Delay Start
o = s:option(Value, "start_delay", translate("Delay Start"), translate("Units:seconds"))
o.default = "1"
o.rmempty = true
---- Automatically turn off time
o = s:option(ListValue, "time_off", translate("Automatically turn off 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
---- Automatically turn on time
o = s:option(ListValue, "time_on", translate("Automatically turn on 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
---- 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
--]]
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:depends(value .. "_week_mode", "0")
o:depends(value .. "_week_mode", "1")
o:depends(value .. "_week_mode", "2")
o:depends(value .. "_week_mode", "3")
o:depends(value .. "_week_mode", "4")
o:depends(value .. "_week_mode", "5")
o:depends(value .. "_week_mode", "6")
o:depends(value .. "_week_mode", "7")
o = s:option(ListValue, value .. "_interval_mode", translate(value .. " Interval(Hour)"))
for t = 1, 24 do o:value(t, t .. " " .. translate("Hour")) end
o.default = 2
o:depends(value .. "_week_mode", "8")
end
-- [[ Forwarding Settings ]]--
s = m:section(TypedSection, "global_forwarding",

View File

@ -10,7 +10,7 @@ local type_name = "Hysteria2"
local option_prefix = "hysteria2_"
local function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -18,59 +18,59 @@ end
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 = 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 = 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 = s:option(Value, option_name("obfs"), translate("Obfs Password"))
o = s:option(Value, _n("obfs"), translate("Obfs Password"))
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.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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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.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.rewrite_option = o.option

View File

@ -10,7 +10,7 @@ local type_name = "Naiveproxy"
local option_prefix = "naive_"
local function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -18,18 +18,18 @@ end
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("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 = 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
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 function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -33,7 +33,7 @@ local xray_version = api.get_app_version("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("vless", translate("VLESS"))
o:value("http", translate("HTTP"))
@ -45,9 +45,9 @@ o:value("_balancing", translate("Balancing"))
o:value("_shunt", translate("Shunt"))
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:depends({ [option_name("protocol")] = "_iface" })
o:depends({ [_n("protocol")] = "_iface" })
local nodes_table = {}
local balancers_table = {}
@ -96,12 +96,12 @@ uci:foreach(appname, "socks", function(s)
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>"))
o:depends({ [option_name("protocol")] = "_balancing" })
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({ [_n("protocol")] = "_balancing" })
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"))
o:depends({ [option_name("protocol")] = "_balancing" })
local o = s:option(ListValue, _n("balancingStrategy"), translate("Balancing Strategy"))
o:depends({ [_n("protocol")] = "_balancing" })
o:value("random")
o:value("roundRobin")
o:value("leastPing")
@ -109,11 +109,11 @@ o.default = "leastPing"
-- Fallback Node
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
o:depends({ [option_name("protocol")] = "_balancing" })
o:depends({ [_n("protocol")] = "_balancing" })
else
o:depends({ [option_name("balancingStrategy")] = "leastPing" })
o:depends({ [_n("balancingStrategy")] = "leastPing" })
end
local function check_fallback_chain(fb)
for k, v in pairs(fallback_table) do
@ -132,11 +132,11 @@ if api.compare_versions(xray_version, ">=", "1.8.10") then
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."))
ucpu:depends({ [option_name("balancingStrategy")] = "leastPing" })
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({ [_n("balancingStrategy")] = "leastPing" })
local pu = s:option(Value, option_name("probeUrl"), translate("Probe URL"))
pu:depends({ [option_name("useCustomProbeUrl")] = true })
local pu = s:option(Value, _n("probeUrl"), translate("Probe URL"))
pu:depends({ [_n("useCustomProbeUrl")] = true })
pu:value("https://cp.cloudflare.com/", "Cloudflare")
pu:value("https://www.gstatic.com/generate_204", "Gstatic")
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.")
-- 探测间隔
local pi = s:option(Value, option_name("probeInterval"), translate("Probe Interval"))
pi:depends({ [option_name("balancingStrategy")] = "leastPing" })
local pi = s:option(Value, _n("probeInterval"), translate("Probe Interval"))
pi:depends({ [_n("balancingStrategy")] = "leastPing" })
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.")
if api.compare_versions(xray_version, ">=", "1.8.12") then
ucpu:depends({ [option_name("protocol")] = "_balancing" })
pi:depends({ [option_name("protocol")] = "_balancing" })
ucpu:depends({ [_n("protocol")] = "_balancing" })
pi:depends({ [_n("protocol")] = "_balancing" })
else
ucpu:depends({ [option_name("balancingStrategy")] = "leastPing" })
pi:depends({ [option_name("balancingStrategy")] = "leastPing" })
ucpu:depends({ [_n("balancingStrategy")] = "leastPing" })
pi:depends({ [_n("balancingStrategy")] = "leastPing" })
end
-- [[ 分流模块 ]]
if #nodes_table > 0 then
o = s:option(Flag, option_name("preproxy_enabled"), translate("Preproxy"))
o:depends({ [option_name("protocol")] = "_shunt" })
o = s:option(Flag, _n("preproxy_enabled"), translate("Preproxy"))
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:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true })
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({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true })
for k, v in pairs(socks_list) do
o:value(v.id, v.remark)
end
@ -180,16 +180,15 @@ if #nodes_table > 0 then
for k, v in pairs(nodes_table) do
o:value(v.id, v.remark)
end
o.default = "nil"
end
uci:foreach(appname, "shunt_rules", function(e)
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:value("nil", translate("Close"))
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("", translate("Close"))
o:value("_default", translate("Default"))
o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole"))
o:depends({ [option_name("protocol")] = "_shunt" })
o:depends({ [_n("protocol")] = "_shunt" })
if #nodes_table > 0 then
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
o:value(v.id, v.remark)
end
local pt = s:option(ListValue, option_name(e[".name"] .. "_proxy_tag"), string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy")))
pt:value("nil", translate("Close"))
local pt = s:option(ListValue, _n(e[".name"] .. "_proxy_tag"), string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy")))
pt:value("", translate("Close"))
pt:value("main", translate("Preproxy Node"))
pt.default = "nil"
for k, v in pairs(nodes_table) do
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)
o = s:option(DummyValue, option_name("shunt_tips"), " ")
o = s:option(DummyValue, _n("shunt_tips"), " ")
o.not_rewrite = true
o.rawhtml = true
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."))
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")))
o:depends({ [option_name("protocol")] = "_shunt" })
local o = s:option(ListValue, _n("default_node"), string.format('* <a style="color:red">%s</a>', translate("Default")))
o:depends({ [_n("protocol")] = "_shunt" })
o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole"))
@ -236,17 +234,16 @@ if #nodes_table > 0 then
for k, v in pairs(iface_table) do
o:value(v.id, v.remark)
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."))
dpt:value("nil", translate("Close"))
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("", translate("Close"))
dpt:value("main", translate("Preproxy Node"))
dpt.default = "nil"
for k, v in pairs(nodes_table) do
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
o = s:option(ListValue, option_name("domainStrategy"), translate("Domain Strategy"))
o = s:option(ListValue, _n("domainStrategy"), translate("Domain Strategy"))
o:value("AsIs")
o:value("IPIfNonMatch")
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("'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately.")
.. "</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("linear")
o:depends({ [option_name("protocol")] = "_shunt" })
o:depends({ [_n("protocol")] = "_shunt" })
-- [[ 分流模块 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"
local protocols = s.fields[option_name("protocol")].keylist
local protocols = s.fields[_n("protocol")].keylist
if #protocols > 0 then
for index, value in ipairs(protocols) do
if not value:find("_") then
s.fields[option_name("address")]:depends({ [option_name("protocol")] = value })
s.fields[option_name("port")]:depends({ [option_name("protocol")] = value })
s.fields[_n("address")]:depends({ [_n("protocol")] = value })
s.fields[_n("port")]:depends({ [_n("protocol")] = value })
end
end
end
o = s:option(Value, option_name("username"), translate("Username"))
o:depends({ [option_name("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "socks" })
o = s:option(Value, _n("username"), translate("Username"))
o:depends({ [_n("protocol")] = "http" })
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:depends({ [option_name("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [_n("protocol")] = "http" })
o:depends({ [_n("protocol")] = "socks" })
o:depends({ [_n("protocol")] = "shadowsocks" })
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
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: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"
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:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "aes-128-gcm" })
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "aes-256-gcm" })
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "chacha20-poly1305" })
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "xchacha20-poly1305" })
o = s:option(Flag, _n("iv_check"), translate("IV Check"))
o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "aes-128-gcm" })
o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "aes-256-gcm" })
o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "chacha20-poly1305" })
o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "xchacha20-poly1305" })
o = s:option(Flag, option_name("uot"), translate("UDP over TCP"))
o:depends({ [option_name("protocol")] = "shadowsocks" })
o = s:option(Flag, _n("uot"), translate("UDP over TCP"))
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:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [_n("protocol")] = "vmess" })
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:value("", translate("Disable"))
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:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "vless" })
o:depends({ [_n("protocol")] = "http" })
o:depends({ [_n("protocol")] = "socks" })
o:depends({ [_n("protocol")] = "trojan" })
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:depends({ [option_name("tls")] = true, [option_name("transport")] = "raw" })
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "h2" })
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "grpc" })
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "xhttp" })
o:depends({ [_n("tls")] = true, [_n("transport")] = "raw" })
o:depends({ [_n("tls")] = true, [_n("transport")] = "h2" })
o:depends({ [_n("tls")] = true, [_n("transport")] = "grpc" })
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:value("default", translate("Default"))
o:value("h3")
@ -349,36 +346,36 @@ o:value("h3,h2")
o:value("http/1.1")
o:value("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: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:depends({ [option_name("tls")] = true })
o = s:option(Value, _n("tls_serverName"), translate("Domain"))
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:depends({ [option_name("tls")] = true, [option_name("reality")] = false })
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
-- [[ REALITY部分 ]] --
o = s:option(Value, option_name("reality_publicKey"), translate("Public Key"))
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true })
o = s:option(Value, _n("reality_publicKey"), translate("Public Key"))
o:depends({ [_n("tls")] = true, [_n("reality")] = true })
o = s:option(Value, option_name("reality_shortId"), translate("Short Id"))
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true })
o = s:option(Value, _n("reality_shortId"), translate("Short Id"))
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: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: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("firefox")
o:value("edge")
@ -390,10 +387,10 @@ o:value("android")
o:value("random")
o:value("randomized")
o.default = "chrome"
o:depends({ [option_name("tls")] = true, [option_name("utls")] = true })
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true })
o:depends({ [_n("tls")] = true, [_n("utls")] = 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("mkcp", "mKCP")
o:value("ws", "WebSocket")
@ -403,193 +400,193 @@ o:value("quic", "QUIC")
o:value("grpc", "gRPC")
o:value("httpupgrade", "HttpUpgrade")
o:value("xhttp", "XHTTP (SplitHTTP)")
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "vless" })
o:depends({ [_n("protocol")] = "socks" })
o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [_n("protocol")] = "trojan" })
o = s:option(Value, option_name("wireguard_public_key"), translate("Public Key"))
o:depends({ [option_name("protocol")] = "wireguard" })
o = s:option(Value, _n("wireguard_public_key"), translate("Public Key"))
o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(Value, option_name("wireguard_secret_key"), translate("Private Key"))
o:depends({ [option_name("protocol")] = "wireguard" })
o = s:option(Value, _n("wireguard_secret_key"), translate("Private Key"))
o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(Value, option_name("wireguard_preSharedKey"), translate("Pre shared key"))
o:depends({ [option_name("protocol")] = "wireguard" })
o = s:option(Value, _n("wireguard_preSharedKey"), translate("Pre shared key"))
o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(DynamicList, option_name("wireguard_local_address"), translate("Local Address"))
o:depends({ [option_name("protocol")] = "wireguard" })
o = s:option(DynamicList, _n("wireguard_local_address"), translate("Local Address"))
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:depends({ [option_name("protocol")] = "wireguard" })
o:depends({ [_n("protocol")] = "wireguard" })
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:depends({ [option_name("protocol")] = "wireguard" })
o = s:option(Value, _n("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings."))
o:depends({ [_n("protocol")] = "wireguard" })
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:depends({ [option_name("protocol")] = "wireguard" })
o:depends({ [_n("protocol")] = "wireguard" })
-- [[ RAW部分 ]]--
-- 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("http", "http")
o:depends({ [option_name("transport")] = "raw" })
o:depends({ [_n("transport")] = "raw" })
-- HTTP域名
o = s:option(DynamicList, option_name("tcp_guise_http_host"), translate("HTTP Host"))
o:depends({ [option_name("tcp_guise")] = "http" })
o = s:option(DynamicList, _n("tcp_guise_http_host"), translate("HTTP Host"))
o:depends({ [_n("tcp_guise")] = "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:depends({ [option_name("tcp_guise")] = "http" })
o:depends({ [_n("tcp_guise")] = "http" })
-- [[ 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
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: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: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: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:depends({ [option_name("transport")] = "mkcp" })
o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Flag, option_name("mkcp_congestion"), translate("KCP Congestion"))
o:depends({ [option_name("transport")] = "mkcp" })
o = s:option(Flag, _n("mkcp_congestion"), translate("KCP Congestion"))
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: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:depends({ [option_name("transport")] = "mkcp" })
o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_seed"), translate("KCP Seed"))
o:depends({ [option_name("transport")] = "mkcp" })
o = s:option(Value, _n("mkcp_seed"), translate("KCP Seed"))
o:depends({ [_n("transport")] = "mkcp" })
-- [[ WebSocket部分 ]]--
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
o:depends({ [option_name("transport")] = "ws" })
o = s:option(Value, _n("ws_host"), translate("WebSocket Host"))
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: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:depends({ [option_name("transport")] = "ws" })
o:depends({ [_n("transport")] = "ws" })
-- [[ HTTP/2部分 ]]--
o = s:option(Value, option_name("h2_host"), translate("HTTP/2 Host"))
o:depends({ [option_name("transport")] = "h2" })
o = s:option(Value, _n("h2_host"), translate("HTTP/2 Host"))
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:depends({ [option_name("transport")] = "h2" })
o:depends({ [_n("transport")] = "h2" })
o = s:option(Flag, option_name("h2_health_check"), translate("Health check"))
o:depends({ [option_name("transport")] = "h2" })
o = s:option(Flag, _n("h2_health_check"), translate("Health check"))
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: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:depends({ [option_name("h2_health_check")] = true })
o:depends({ [_n("h2_health_check")] = true })
-- [[ DomainSocket部分 ]]--
o = s:option(Value, option_name("ds_path"), "Path", translate("A legal file path. This file must not exist before running."))
o:depends({ [option_name("transport")] = "ds" })
o = s:option(Value, _n("ds_path"), "Path", translate("A legal file path. This file must not exist before running."))
o:depends({ [_n("transport")] = "ds" })
-- [[ 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("aes-128-gcm")
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:depends({ [option_name("transport")] = "quic" })
o = s:option(Value, _n("quic_key"), translate("Encrypt Method") .. translate("Key"))
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
o:depends({ [option_name("transport")] = "quic" })
o:depends({ [_n("transport")] = "quic" })
-- [[ gRPC部分 ]]--
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName")
o:depends({ [option_name("transport")] = "grpc" })
o = s:option(Value, _n("grpc_serviceName"), "ServiceName")
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("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:depends({ [option_name("transport")] = "grpc" })
o = s:option(Flag, _n("grpc_health_check"), translate("Health check"))
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: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: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: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:depends({ [option_name("transport")] = "grpc" })
o:depends({ [_n("transport")] = "grpc" })
-- [[ HttpUpgrade部分 ]]--
o = s:option(Value, option_name("httpupgrade_host"), translate("HttpUpgrade Host"))
o:depends({ [option_name("transport")] = "httpupgrade" })
o = s:option(Value, _n("httpupgrade_host"), translate("HttpUpgrade Host"))
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:depends({ [option_name("transport")] = "httpupgrade" })
o:depends({ [_n("transport")] = "httpupgrade" })
-- [[ XHTTP部分 ]]--
o = s:option(ListValue, option_name("xhttp_mode"), "XHTTP " .. translate("Mode"))
o:depends({ [option_name("transport")] = "xhttp" })
o = s:option(ListValue, _n("xhttp_mode"), "XHTTP " .. translate("Mode"))
o:depends({ [_n("transport")] = "xhttp" })
o.default = "auto"
o:value("auto")
o:value("packet-up")
o:value("stream-up")
o:value("stream-one")
o = s:option(Value, option_name("xhttp_host"), translate("XHTTP Host"))
o:depends({ [option_name("transport")] = "xhttp" })
o = s:option(Value, _n("xhttp_host"), translate("XHTTP Host"))
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: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:depends({ [option_name("transport")] = "xhttp" })
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({ [_n("transport")] = "xhttp" })
o.rows = 15
o.wrap = "off"
o.custom_write = function(self, section, value)
@ -618,62 +615,62 @@ o.validate = function(self, value)
end
-- [[ Mux.Cool ]]--
o = s:option(Flag, option_name("mux"), "Mux", translate("Enable Mux.Cool"))
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless", [option_name("flow")] = "" })
o:depends({ [option_name("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" })
o = s:option(Flag, _n("mux"), "Mux", translate("Enable Mux.Cool"))
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "vless", [_n("flow")] = "" })
o:depends({ [_n("protocol")] = "http" })
o:depends({ [_n("protocol")] = "socks" })
o:depends({ [_n("protocol")] = "shadowsocks" })
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:depends({ [option_name("mux")] = true })
o:depends({ [_n("mux")] = true })
-- [[ XUDP Mux ]]--
o = s:option(Flag, option_name("xmux"), "XUDP Mux")
o = s:option(Flag, _n("xmux"), "XUDP Mux")
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:depends({ [option_name("xmux")] = true })
o:depends({ [_n("xmux")] = true })
--[[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 = s:option(Flag, option_name("tcpNoDelay"), "tcpNoDelay")
o = s:option(Flag, _n("tcpNoDelay"), "tcpNoDelay")
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("1", translate("Preproxy 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
o:depends({ [option_name("protocol")] = v })
o:depends({ [_n("protocol")] = v })
end
end
o = s:option(ListValue, option_name("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
o:depends({ [option_name("chain_proxy")] = "1" })
o = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
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:depends({ [option_name("chain_proxy")] = "2" })
o = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
o:depends({ [_n("chain_proxy")] = "2" })
for k, v in pairs(nodes_table) do
if v.type == "Xray" and v.id ~= arg[1] then
s.fields[option_name("preproxy_node")]:value(v.id, v.remark)
s.fields[option_name("to_node")]:value(v.id, v.remark)
s.fields[_n("preproxy_node")]:value(v.id, v.remark)
s.fields[_n("to_node")]:value(v.id, v.remark)
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
s.fields[option_name("tcpMptcp")]:depends({ [option_name("protocol")] = v })
s.fields[option_name("tcpNoDelay")]:depends({ [option_name("protocol")] = v })
s.fields[option_name("chain_proxy")]:depends({ [option_name("protocol")] = v })
s.fields[_n("tcpMptcp")]:depends({ [_n("protocol")] = v })
s.fields[_n("tcpNoDelay")]:depends({ [_n("protocol")] = v })
s.fields[_n("chain_proxy")]:depends({ [_n("protocol")] = v })
end
end

View File

@ -17,7 +17,7 @@ local type_name = "sing-box"
local option_prefix = "singbox_"
local function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -35,7 +35,7 @@ local security_list = { "none", "auto", "aes-128-gcm", "chacha20-poly1305", "zer
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("http", "HTTP")
o:value("shadowsocks", "Shadowsocks")
@ -60,9 +60,9 @@ end
o:value("_shunt", translate("Shunt"))
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:depends({ [option_name("protocol")] = "_iface" })
o:depends({ [_n("protocol")] = "_iface" })
local nodes_table = {}
local iface_table = {}
@ -94,11 +94,11 @@ end)
-- [[ 分流模块 ]]
if #nodes_table > 0 then
o = s:option(Flag, option_name("preproxy_enabled"), translate("Preproxy"))
o:depends({ [option_name("protocol")] = "_shunt" })
o = s:option(Flag, _n("preproxy_enabled"), translate("Preproxy"))
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:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true })
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({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true })
for k, v in pairs(socks_list) do
o:value(v.id, v.remark)
end
@ -108,16 +108,15 @@ if #nodes_table > 0 then
for k, v in pairs(nodes_table) do
o:value(v.id, v.remark)
end
o.default = "nil"
end
uci:foreach(appname, "shunt_rules", function(e)
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:value("nil", translate("Close"))
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("", translate("Close"))
o:value("_default", translate("Default"))
o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole"))
o:depends({ [option_name("protocol")] = "_shunt" })
o:depends({ [_n("protocol")] = "_shunt" })
if #nodes_table > 0 then
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
o:value(v.id, v.remark)
end
local pt = s:option(ListValue, option_name(e[".name"] .. "_proxy_tag"), string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy")))
pt:value("nil", translate("Close"))
local pt = s:option(ListValue, _n(e[".name"] .. "_proxy_tag"), string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy")))
pt:value("", translate("Close"))
pt:value("main", translate("Preproxy Node"))
pt.default = "nil"
for k, v in pairs(nodes_table) do
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)
o = s:option(DummyValue, option_name("shunt_tips"), " ")
o = s:option(DummyValue, _n("shunt_tips"), " ")
o.not_rewrite = true
o.rawhtml = true
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."))
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")))
o:depends({ [option_name("protocol")] = "_shunt" })
local o = s:option(ListValue, _n("default_node"), string.format('* <a style="color:red">%s</a>', translate("Default")))
o:depends({ [_n("protocol")] = "_shunt" })
o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole"))
@ -158,61 +156,60 @@ if #nodes_table > 0 then
for k, v in pairs(iface_table) do
o:value(v.id, v.remark)
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."))
dpt:value("nil", translate("Close"))
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("", translate("Close"))
dpt:value("main", translate("Preproxy Node"))
dpt.default = "nil"
for k, v in pairs(nodes_table) do
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 ]]
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"
local protocols = s.fields[option_name("protocol")].keylist
local protocols = s.fields[_n("protocol")].keylist
if #protocols > 0 then
for index, value in ipairs(protocols) do
if not value:find("_") then
s.fields[option_name("address")]:depends({ [option_name("protocol")] = value })
s.fields[option_name("port")]:depends({ [option_name("protocol")] = value })
s.fields[_n("address")]:depends({ [_n("protocol")] = value })
s.fields[_n("port")]:depends({ [_n("protocol")] = value })
end
end
end
o = s:option(Value, option_name("username"), translate("Username"))
o:depends({ [option_name("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "socks" })
o = s:option(Value, _n("username"), translate("Username"))
o:depends({ [_n("protocol")] = "http" })
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:depends({ [option_name("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "shadowsocksr" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [option_name("protocol")] = "tuic" })
o:depends({ [_n("protocol")] = "http" })
o:depends({ [_n("protocol")] = "socks" })
o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [_n("protocol")] = "shadowsocksr" })
o:depends({ [_n("protocol")] = "trojan" })
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
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"
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
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [_n("protocol")] = "shadowsocks" })
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"
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 = {
"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"
}
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
o:depends({ [option_name("protocol")] = "shadowsocksr" })
o:depends({ [_n("protocol")] = "shadowsocksr" })
o = s:option(Value, option_name("ssr_protocol_param"), translate("Protocol_param"))
o:depends({ [option_name("protocol")] = "shadowsocksr" })
o = s:option(Value, _n("ssr_protocol_param"), translate("Protocol_param"))
o:depends({ [_n("protocol")] = "shadowsocksr" })
local ssr_obfs_list = {
"plain", "http_simple", "http_post", "random_head", "tls_simple",
"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
o:depends({ [option_name("protocol")] = "shadowsocksr" })
o:depends({ [_n("protocol")] = "shadowsocksr" })
o = s:option(Value, option_name("ssr_obfs_param"), translate("Obfs_param"))
o:depends({ [option_name("protocol")] = "shadowsocksr" })
o = s:option(Value, _n("ssr_obfs_param"), translate("Obfs_param"))
o:depends({ [_n("protocol")] = "shadowsocksr" })
end
o = s:option(Flag, option_name("uot"), translate("UDP over TCP"))
o:depends({ [option_name("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o = s:option(Flag, _n("uot"), translate("UDP over TCP"))
o:depends({ [_n("protocol")] = "socks" })
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:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "tuic" })
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "vless" })
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.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: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: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:value("", translate("Disable"))
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
o = s:option(Value, option_name("hysteria_obfs"), translate("Obfs Password"))
o:depends({ [option_name("protocol")] = "hysteria" })
o = s:option(Value, _n("hysteria_obfs"), translate("Obfs Password"))
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("string", translate("STRING"))
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:depends({ [option_name("protocol")] = "hysteria", [option_name("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")] = "string"})
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: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: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:depends({ [option_name("protocol")] = "hysteria" })
o = s:option(Value, _n("hysteria_recv_window_conn"), translate("QUIC stream receive window"))
o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_recv_window"), translate("QUIC connection receive window"))
o:depends({ [option_name("protocol")] = "hysteria" })
o = s:option(Value, _n("hysteria_recv_window"), translate("QUIC connection receive window"))
o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Flag, option_name("hysteria_disable_mtu_discovery"), translate("Disable MTU detection"))
o:depends({ [option_name("protocol")] = "hysteria" })
o = s:option(Flag, _n("hysteria_disable_mtu_discovery"), translate("Disable MTU detection"))
o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_alpn"), translate("QUIC TLS ALPN"))
o:depends({ [option_name("protocol")] = "hysteria" })
o = s:option(Value, _n("hysteria_alpn"), translate("QUIC TLS ALPN"))
o:depends({ [_n("protocol")] = "hysteria" })
end
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:value("bbr", translate("BBR"))
o:value("cubic", translate("CUBIC"))
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:value("native", translate("native"))
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:depends({ [option_name("protocol")] = "tuic" })
o = s:option(Flag, _n("tuic_udp_over_stream"), translate("UDP over stream"))
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: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.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:value("default", translate("Default"))
o:value("h3")
@ -343,38 +340,38 @@ if singbox_tags:find("with_quic") then
o:value("http/1.1")
o:value("h2,http/1.1")
o:value("h3,h2,http/1.1")
o:depends({ [option_name("protocol")] = "tuic" })
o:depends({ [_n("protocol")] = "tuic" })
end
if singbox_tags:find("with_quic") then
o = s:option(Value, option_name("hysteria2_up_mbps"), translate("Max upload Mbps"))
o:depends({ [option_name("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, option_name("hysteria2_down_mbps"), translate("Max download Mbps"))
o:depends({ [option_name("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps"))
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("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:depends({ [option_name("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
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:depends({ [option_name("protocol")] = "hysteria2"})
o:depends({ [_n("protocol")] = "hysteria2"})
end
o = s:option(Flag, option_name("tls"), translate("TLS"))
o = s:option(Flag, _n("tls"), translate("TLS"))
o.default = 0
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "vless" })
o:depends({ [_n("protocol")] = "http" })
o:depends({ [_n("protocol")] = "trojan" })
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:value("default", translate("Default"))
o:value("h3")
@ -383,36 +380,36 @@ o:value("h3,h2")
o:value("http/1.1")
o:value("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:depends({ [option_name("tls")] = true })
o:depends({ [option_name("protocol")] = "hysteria"})
o:depends({ [option_name("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria2" })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o = s:option(Value, _n("tls_serverName"), translate("Domain"))
o:depends({ [_n("tls")] = true })
o:depends({ [_n("protocol")] = "hysteria"})
o:depends({ [_n("protocol")] = "tuic" })
o:depends({ [_n("protocol")] = "hysteria2" })
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:depends({ [option_name("tls")] = true })
o:depends({ [option_name("protocol")] = "hysteria"})
o:depends({ [option_name("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria2" })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [_n("tls")] = true })
o:depends({ [_n("protocol")] = "hysteria"})
o:depends({ [_n("protocol")] = "tuic" })
o:depends({ [_n("protocol")] = "hysteria2" })
o:depends({ [_n("protocol")] = "shadowsocks" })
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:depends({ [option_name("tls")] = true, [option_name("flow")] = "", [option_name("reality")] = false })
o:depends({ [option_name("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria" })
o:depends({ [option_name("protocol")] = "hysteria2" })
o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
o:depends({ [_n("protocol")] = "tuic" })
o:depends({ [_n("protocol")] = "hysteria" })
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.rows = 5
o.wrap = "off"
o:depends({ [option_name("ech")] = true })
o:depends({ [_n("ech")] = true })
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*\n", "")
@ -422,21 +419,21 @@ if singbox_tags:find("with_ech") then
return value
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: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:depends({ [option_name("ech")] = true })
o:depends({ [_n("ech")] = true })
end
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: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("firefox")
o:value("edge")
@ -448,25 +445,25 @@ if singbox_tags:find("with_utls") then
o:value("random")
-- o:value("randomized")
o.default = "chrome"
o:depends({ [option_name("tls")] = true, [option_name("utls")] = true })
o:depends({ [_n("tls")] = true, [_n("utls")] = true })
-- [[ REALITY部分 ]] --
o = s:option(Flag, option_name("reality"), translate("REALITY"))
o = s:option(Flag, _n("reality"), translate("REALITY"))
o.default = 0
o:depends({ [option_name("protocol")] = "vless", [option_name("utls")] = true })
o:depends({ [option_name("protocol")] = "vmess", [option_name("utls")] = true })
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("utls")] = true })
o:depends({ [option_name("protocol")] = "socks", [option_name("utls")] = true })
o:depends({ [option_name("protocol")] = "trojan", [option_name("utls")] = true })
o:depends({ [_n("protocol")] = "vless", [_n("utls")] = true })
o:depends({ [_n("protocol")] = "vmess", [_n("utls")] = true })
o:depends({ [_n("protocol")] = "shadowsocks", [_n("utls")] = true })
o:depends({ [_n("protocol")] = "socks", [_n("utls")] = true })
o:depends({ [_n("protocol")] = "trojan", [_n("utls")] = true })
o = s:option(Value, option_name("reality_publicKey"), translate("Public Key"))
o:depends({ [option_name("utls")] = true, [option_name("reality")] = true })
o = s:option(Value, _n("reality_publicKey"), translate("Public Key"))
o:depends({ [_n("utls")] = true, [_n("reality")] = true })
o = s:option(Value, option_name("reality_shortId"), translate("Short Id"))
o:depends({ [option_name("utls")] = true, [option_name("reality")] = true })
o = s:option(Value, _n("reality_shortId"), translate("Short Id"))
o:depends({ [_n("utls")] = true, [_n("reality")] = true })
end
o = s:option(ListValue, option_name("transport"), translate("Transport"))
o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("tcp", "TCP")
o:value("http", "HTTP")
o:value("ws", "WebSocket")
@ -478,158 +475,158 @@ if singbox_tags:find("with_grpc") then
o:value("grpc", "gRPC")
else o:value("grpc", "gRPC-lite")
end
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "vless" })
o:depends({ [_n("protocol")] = "socks" })
o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [_n("protocol")] = "trojan" })
if singbox_tags:find("with_wireguard") then
o = s:option(Value, option_name("wireguard_public_key"), translate("Public Key"))
o:depends({ [option_name("protocol")] = "wireguard" })
o = s:option(Value, _n("wireguard_public_key"), translate("Public Key"))
o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(Value, option_name("wireguard_secret_key"), translate("Private Key"))
o:depends({ [option_name("protocol")] = "wireguard" })
o = s:option(Value, _n("wireguard_secret_key"), translate("Private Key"))
o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(Value, option_name("wireguard_preSharedKey"), translate("Pre shared key"))
o:depends({ [option_name("protocol")] = "wireguard" })
o = s:option(Value, _n("wireguard_preSharedKey"), translate("Pre shared key"))
o:depends({ [_n("protocol")] = "wireguard" })
o = s:option(DynamicList, option_name("wireguard_local_address"), translate("Local Address"))
o:depends({ [option_name("protocol")] = "wireguard" })
o = s:option(DynamicList, _n("wireguard_local_address"), translate("Local Address"))
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: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:depends({ [option_name("protocol")] = "wireguard" })
o = s:option(Value, _n("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings."))
o:depends({ [_n("protocol")] = "wireguard" })
end
-- [[ HTTP部分 ]]--
o = s:option(Value, option_name("http_host"), translate("HTTP Host"))
o:depends({ [option_name("transport")] = "http" })
o = s:option(Value, _n("http_host"), translate("HTTP Host"))
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:depends({ [option_name("transport")] = "http" })
o:depends({ [_n("transport")] = "http" })
o = s:option(Flag, option_name("http_h2_health_check"), translate("Health check"))
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "http" })
o = s:option(Flag, _n("http_h2_health_check"), translate("Health check"))
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: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: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部分 ]]--
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
o:depends({ [option_name("transport")] = "ws" })
o = s:option(Value, _n("ws_host"), translate("WebSocket Host"))
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:depends({ [option_name("transport")] = "ws" })
o:depends({ [_n("transport")] = "ws" })
o = s:option(Flag, option_name("ws_enableEarlyData"), translate("Enable early data"))
o:depends({ [option_name("transport")] = "ws" })
o = s:option(Flag, _n("ws_enableEarlyData"), translate("Enable early data"))
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: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:depends({ [option_name("ws_enableEarlyData")] = true })
o = s:option(Value, _n("ws_earlyDataHeaderName"), translate("Early data header name"), translate("Recommended value: Sec-WebSocket-Protocol"))
o:depends({ [_n("ws_enableEarlyData")] = true })
-- [[ HTTPUpgrade部分 ]]--
o = s:option(Value, option_name("httpupgrade_host"), translate("HTTPUpgrade Host"))
o:depends({ [option_name("transport")] = "httpupgrade" })
o = s:option(Value, _n("httpupgrade_host"), translate("HTTPUpgrade Host"))
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:depends({ [option_name("transport")] = "httpupgrade" })
o:depends({ [_n("transport")] = "httpupgrade" })
-- [[ gRPC部分 ]]--
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName")
o:depends({ [option_name("transport")] = "grpc" })
o = s:option(Value, _n("grpc_serviceName"), "ServiceName")
o:depends({ [_n("transport")] = "grpc" })
o = s:option(Flag, option_name("grpc_health_check"), translate("Health check"))
o:depends({ [option_name("transport")] = "grpc" })
o = s:option(Flag, _n("grpc_health_check"), translate("Health check"))
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: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: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:depends({ [option_name("grpc_health_check")] = true })
o:depends({ [_n("grpc_health_check")] = true })
-- [[ Mux ]]--
o = s:option(Flag, option_name("mux"), translate("Mux"))
o = s:option(Flag, _n("mux"), translate("Mux"))
o.rmempty = false
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless", [option_name("flow")] = "" })
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("uot")] = "" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "vless", [_n("flow")] = "" })
o:depends({ [_n("protocol")] = "shadowsocks", [_n("uot")] = "" })
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("yamux")
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: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:depends({ [option_name("mux")] = true })
o:depends({ [_n("mux")] = true })
-- [[ 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: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: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: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:depends({ [option_name("protocol")] = "vmess", [option_name("tls")] = false })
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("tls")] = false })
o:depends({ [_n("protocol")] = "vmess", [_n("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:value("1", "ShadowTLS v1")
o:value("2", "ShadowTLS v2")
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:depends({ [option_name("shadowtls")] = true, [option_name("shadowtls_version")] = "2" })
o:depends({ [option_name("shadowtls")] = true, [option_name("shadowtls_version")] = "3" })
o:depends({ [_n("shadowtls")] = true, [_n("shadowtls_version")] = "2" })
o:depends({ [_n("shadowtls")] = true, [_n("shadowtls_version")] = "3" })
o = s:option(Value, option_name("shadowtls_serverName"), "ShadowTLS " .. translate("Domain"))
o:depends({ [option_name("shadowtls")] = true })
o = s:option(Value, _n("shadowtls_serverName"), "ShadowTLS " .. translate("Domain"))
o:depends({ [_n("shadowtls")] = true })
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: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("firefox")
o:value("edge")
@ -641,62 +638,62 @@ if singbox_tags:find("with_utls") then
o:value("random")
-- o:value("randomized")
o.default = "chrome"
o:depends({ [option_name("shadowtls")] = true, [option_name("shadowtls_utls")] = true })
o:depends({ [_n("shadowtls")] = true, [_n("shadowtls_utls")] = true })
end
-- [[ 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: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:depends({ [option_name("plugin_enabled")] = true })
o:depends({ [_n("plugin_enabled")] = true })
o:value("obfs-local")
o:value("v2ray-plugin")
o = s:option(Value, option_name("plugin_opts"), translate("opts"))
o:depends({ [option_name("plugin_enabled")] = true })
o = s:option(Value, _n("plugin_opts"), translate("opts"))
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:value("", translate("Auto"))
o:value("prefer_ipv4", translate("Prefer IPv4"))
o:value("prefer_ipv6", translate("Prefer IPv6"))
o:value("ipv4_only", translate("IPv4 Only"))
o:value("ipv6_only", translate("IPv6 Only"))
o:depends({ [option_name("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "shadowsocksr" })
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [option_name("protocol")] = "wireguard" })
o:depends({ [option_name("protocol")] = "hysteria" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria2" })
o:depends({ [_n("protocol")] = "socks" })
o:depends({ [_n("protocol")] = "http" })
o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [_n("protocol")] = "shadowsocksr" })
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "trojan" })
o:depends({ [_n("protocol")] = "wireguard" })
o:depends({ [_n("protocol")] = "hysteria" })
o:depends({ [_n("protocol")] = "vless" })
o:depends({ [_n("protocol")] = "tuic" })
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("1", translate("Preproxy 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
o:depends({ [option_name("protocol")] = v })
o:depends({ [_n("protocol")] = v })
end
end
o = s:option(ListValue, option_name("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
o:depends({ [option_name("chain_proxy")] = "1" })
o = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
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:depends({ [option_name("chain_proxy")] = "2" })
o = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
o:depends({ [_n("chain_proxy")] = "2" })
for k, v in pairs(nodes_table) do
if v.type == "sing-box" and v.id ~= arg[1] then
s.fields[option_name("preproxy_node")]:value(v.id, v.remark)
s.fields[option_name("to_node")]:value(v.id, v.remark)
s.fields[_n("preproxy_node")]:value(v.id, v.remark)
s.fields[_n("to_node")]:value(v.id, v.remark)
end
end

View File

@ -10,7 +10,7 @@ local type_name = "SS-Rust"
local option_prefix = "ssrust_"
local function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -24,34 +24,34 @@ local ssrust_encrypt_method_list = {
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 = s:option(Value, option_name("password"), translate("Password"))
o = s:option(Value, _n("password"), translate("Password"))
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
o = s:option(Value, option_name("timeout"), translate("Connection Timeout"))
o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger"
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("true")
o = s:option(ListValue, option_name("plugin"), translate("plugin"))
o = s:option(ListValue, _n("plugin"), translate("plugin"))
o:value("none", translate("none"))
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("obfs-local") then o:value("obfs-local") end
o = s:option(Value, option_name("plugin_opts"), translate("opts"))
o:depends({ [option_name("plugin")] = "xray-plugin"})
o:depends({ [option_name("plugin")] = "v2ray-plugin"})
o:depends({ [option_name("plugin")] = "obfs-local"})
o = s:option(Value, _n("plugin_opts"), translate("opts"))
o:depends({ [_n("plugin")] = "xray-plugin"})
o:depends({ [_n("plugin")] = "v2ray-plugin"})
o:depends({ [_n("plugin")] = "obfs-local"})
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 function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -25,34 +25,34 @@ local ss_encrypt_method_list = {
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 = s:option(Value, option_name("password"), translate("Password"))
o = s:option(Value, _n("password"), translate("Password"))
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
o = s:option(Value, option_name("timeout"), translate("Connection Timeout"))
o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger"
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("true")
o = s:option(ListValue, option_name("plugin"), translate("plugin"))
o = s:option(ListValue, _n("plugin"), translate("plugin"))
o:value("none", translate("none"))
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("obfs-local") then o:value("obfs-local") end
o = s:option(Value, option_name("plugin_opts"), translate("opts"))
o:depends({ [option_name("plugin")] = "xray-plugin"})
o:depends({ [option_name("plugin")] = "v2ray-plugin"})
o:depends({ [option_name("plugin")] = "obfs-local"})
o = s:option(Value, _n("plugin_opts"), translate("opts"))
o:depends({ [_n("plugin")] = "xray-plugin"})
o:depends({ [_n("plugin")] = "v2ray-plugin"})
o:depends({ [_n("plugin")] = "obfs-local"})
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 function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -37,32 +37,32 @@ local ssr_obfs_list = {
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 = s:option(Value, option_name("password"), translate("Password"))
o = s:option(Value, _n("password"), translate("Password"))
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
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
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
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.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("true")

View File

@ -10,7 +10,7 @@ local type_name = "Trojan-Plus"
local option_prefix = "trojan_plus_"
local function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -18,19 +18,19 @@ end
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 = s:option(Value, option_name("password"), translate("Password"))
o = s:option(Value, _n("password"), translate("Password"))
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("true")
o = s:option(Flag, option_name("tls"), translate("TLS"))
o = s:option(Flag, _n("tls"), translate("TLS"))
o.default = 0
o.validate = function(self, value, t)
if value then
@ -42,15 +42,15 @@ o.validate = function(self, value, t)
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:depends({ [option_name("tls")] = true })
o:depends({ [_n("tls")] = true })
o = s:option(Value, option_name("tls_serverName"), translate("Domain"))
o:depends({ [option_name("tls")] = true })
o = s:option(Value, _n("tls_serverName"), translate("Domain"))
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:depends({ [option_name("tls")] = true })
o:depends({ [_n("tls")] = true })
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 function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -18,16 +18,16 @@ end
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 = s:option(Value, option_name("uuid"), translate("ID"))
o = s:option(Value, _n("uuid"), translate("ID"))
o.password = true
-- 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.rmempty = true
o.default = ""
@ -35,32 +35,32 @@ o.rewrite_option = o.option
--[[
-- 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.default = ""
o.rewrite_option = o.option
-- 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.rmempty = true
o.default = ""
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.rmempty = true
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("quic", translate("QUIC"))
o.default = "native"
o.rmempty = true
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("cubic", translate("CUBIC"))
o:value("new_reno", translate("New Reno"))
@ -68,65 +68,65 @@ o.default = "cubic"
o.rmempty = true
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.default = "3"
o.rmempty = true
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.default = "8"
o.rmempty = true
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.default = "3"
o.rmempty = true
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.default = "15"
o.rmempty = true
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.default = 20971520
o.rmempty = true
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.default = 10485760
o.rmempty = true
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.default = 1500
o.rmempty = true
o.rewrite_option = o.option
--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.rmempty = true
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.rmempty = true
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.rmempty = true
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.rewrite_option = o.option

View File

@ -10,7 +10,7 @@ local type_name = "Hysteria2"
local option_prefix = "hysteria2_"
local function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -18,31 +18,31 @@ end
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 = s:option(Value, option_name("obfs"), translate("Obfs Password"))
o = s:option(Value, _n("obfs"), translate("Obfs Password"))
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.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.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 = 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 = s:option(Flag, option_name("ignoreClientBandwidth"), translate("ignoreClientBandwidth"))
o = s:option(Flag, _n("ignoreClientBandwidth"), translate("ignoreClientBandwidth"))
o.default = "0"
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.validate = function(self, value, t)
if value and value ~= "" then
@ -55,7 +55,7 @@ o.validate = function(self, value, t)
return nil
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.validate = function(self, value, t)
if value and value ~= "" then
@ -68,7 +68,7 @@ o.validate = function(self, value, t)
return nil
end
o = s:option(Flag, option_name("log"), translate("Log"))
o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1"
o.rmempty = false

View File

@ -10,7 +10,7 @@ local type_name = "Xray"
local option_prefix = "xray_"
local function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -26,7 +26,7 @@ local header_type_list = {
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("vless", "VLESS")
o:value("http", "HTTP")
@ -35,91 +35,91 @@ o:value("shadowsocks", "Shadowsocks")
o:value("trojan", "Trojan")
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 = s:option(Flag, option_name("auth"), translate("Auth"))
o = s:option(Flag, _n("auth"), translate("Auth"))
o.validate = function(self, value, t)
if value and value == "1" then
local user_v = s.fields[option_name("username")] and s.fields[option_name("username")]:formvalue(t) or ""
local pass_v = s.fields[option_name("password")] and s.fields[option_name("password")]:formvalue(t) or ""
local user_v = s.fields[_n("username")] and s.fields[_n("username")]: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
return nil, translate("Username and Password must be used together!")
end
end
return value
end
o:depends({ [option_name("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "http" })
o:depends({ [_n("protocol")] = "socks" })
o:depends({ [_n("protocol")] = "http" })
o = s:option(Value, option_name("username"), translate("Username"))
o:depends({ [option_name("auth")] = true })
o = s:option(Value, _n("username"), translate("Username"))
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:depends({ [option_name("auth")] = true })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [_n("auth")] = true })
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("udp", "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:depends({ [option_name("protocol")] = "dokodemo-door" })
o = s:option(Value, _n("d_address"), translate("Destination address"))
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: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: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"
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:depends({ [option_name("protocol")] = "shadowsocks" })
o = s:option(Flag, _n("iv_check"), translate("IV Check"))
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:value("tcp", "TCP")
o:value("udp", "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.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
o:value(api.gen_uuid(1))
end
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "vless" })
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:value("", translate("Disable"))
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.validate = function(self, value, t)
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 value == "1" then
local ca = s.fields[option_name("tls_certificateFile")] and s.fields[option_name("tls_certificateFile")]:formvalue(t) or ""
local key = s.fields[option_name("tls_keyFile")] and s.fields[option_name("tls_keyFile")]:formvalue(t) or ""
local ca = s.fields[_n("tls_certificateFile")] and s.fields[_n("tls_certificateFile")]:formvalue(t) or ""
local key = s.fields[_n("tls_keyFile")] and s.fields[_n("tls_keyFile")]:formvalue(t) or ""
if ca == "" or key == "" then
return nil, translate("Public key and Private key path can not be empty!")
end
@ -127,32 +127,32 @@ o.validate = function(self, value, t)
return value
end
end
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "vless" })
o:depends({ [_n("protocol")] = "http" })
o:depends({ [_n("protocol")] = "socks" })
o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [_n("protocol")] = "trojan" })
-- [[ REALITY部分 ]] --
o = s:option(Flag, option_name("reality"), translate("REALITY"))
o = s:option(Flag, _n("reality"), translate("REALITY"))
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:depends({ [option_name("reality")] = true })
o = s:option(Value, _n("reality_private_key"), translate("Private Key"))
o:depends({ [_n("reality")] = true })
o = s:option(DynamicList, option_name("reality_shortId"), translate("Short Id"))
o:depends({ [option_name("reality")] = true })
o = s:option(DynamicList, _n("reality_shortId"), translate("Short Id"))
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:depends({ [option_name("reality")] = true })
o:depends({ [_n("reality")] = true })
o = s:option(Value, option_name("reality_serverNames"), translate("serverNames"))
o:depends({ [option_name("reality")] = true })
o = s:option(Value, _n("reality_serverNames"), translate("serverNames"))
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:value("h3")
o:value("h2")
@ -160,18 +160,18 @@ o:value("h3,h2")
o:value("http/1.1")
o:value("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:value("1.3")
--o:depends({ [option_name("tls")] = true })
--o:depends({ [_n("tls")] = true })
-- [[ 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:depends({ [option_name("tls")] = true, [option_name("reality")] = false })
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@ -183,9 +183,9 @@ o.validate = function(self, value, t)
return nil
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:depends({ [option_name("tls")] = true, [option_name("reality")] = false })
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@ -197,7 +197,7 @@ o.validate = function(self, value, t)
return nil
end
o = s:option(ListValue, option_name("transport"), translate("Transport"))
o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("raw", "RAW")
o:value("mkcp", "mKCP")
o:value("ws", "WebSocket")
@ -207,157 +207,157 @@ o:value("quic", "QUIC")
o:value("grpc", "gRPC")
o:value("httpupgrade", "HttpUpgrade")
o:value("xhttp", "XHTTP")
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "vless" })
o:depends({ [_n("protocol")] = "socks" })
o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [_n("protocol")] = "trojan" })
-- [[ WebSocket部分 ]]--
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
o:depends({ [option_name("transport")] = "ws" })
o = s:option(Value, _n("ws_host"), translate("WebSocket Host"))
o:depends({ [_n("transport")] = "ws" })
o = s:option(Value, option_name("ws_path"), translate("WebSocket Path"))
o:depends({ [option_name("transport")] = "ws" })
o = s:option(Value, _n("ws_path"), translate("WebSocket Path"))
o:depends({ [_n("transport")] = "ws" })
-- [[ HttpUpgrade部分 ]]--
o = s:option(Value, option_name("httpupgrade_host"), translate("HttpUpgrade Host"))
o:depends({ [option_name("transport")] = "httpupgrade" })
o = s:option(Value, _n("httpupgrade_host"), translate("HttpUpgrade Host"))
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:depends({ [option_name("transport")] = "httpupgrade" })
o:depends({ [_n("transport")] = "httpupgrade" })
-- [[ SplitHTTP部分 ]]--
o = s:option(Value, option_name("xhttp_host"), translate("XHTTP Host"))
o:depends({ [option_name("transport")] = "xhttp" })
o = s:option(Value, _n("xhttp_host"), translate("XHTTP Host"))
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: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: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:depends({ [option_name("transport")] = "xhttp" })
o:depends({ [_n("transport")] = "xhttp" })
-- [[ HTTP/2部分 ]]--
o = s:option(Value, option_name("h2_host"), translate("HTTP/2 Host"))
o:depends({ [option_name("transport")] = "h2" })
o = s:option(Value, _n("h2_host"), translate("HTTP/2 Host"))
o:depends({ [_n("transport")] = "h2" })
o = s:option(Value, option_name("h2_path"), translate("HTTP/2 Path"))
o:depends({ [option_name("transport")] = "h2" })
o = s:option(Value, _n("h2_path"), translate("HTTP/2 Path"))
o:depends({ [_n("transport")] = "h2" })
-- [[ 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("http", "http")
o:depends({ [option_name("transport")] = "raw" })
o:depends({ [_n("transport")] = "raw" })
-- HTTP域名
o = s:option(DynamicList, option_name("tcp_guise_http_host"), translate("HTTP Host"))
o:depends({ [option_name("tcp_guise")] = "http" })
o = s:option(DynamicList, _n("tcp_guise_http_host"), translate("HTTP Host"))
o:depends({ [_n("tcp_guise")] = "http" })
-- HTTP路径
o = s:option(DynamicList, option_name("tcp_guise_http_path"), translate("HTTP Path"))
o:depends({ [option_name("tcp_guise")] = "http" })
o = s:option(DynamicList, _n("tcp_guise_http_path"), translate("HTTP Path"))
o:depends({ [_n("tcp_guise")] = "http" })
-- [[ 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
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: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: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: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:depends({ [option_name("transport")] = "mkcp" })
o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Flag, option_name("mkcp_congestion"), translate("KCP Congestion"))
o:depends({ [option_name("transport")] = "mkcp" })
o = s:option(Flag, _n("mkcp_congestion"), translate("KCP Congestion"))
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: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:depends({ [option_name("transport")] = "mkcp" })
o:depends({ [_n("transport")] = "mkcp" })
o = s:option(Value, option_name("mkcp_seed"), translate("KCP Seed"))
o:depends({ [option_name("transport")] = "mkcp" })
o = s:option(Value, _n("mkcp_seed"), translate("KCP Seed"))
o:depends({ [_n("transport")] = "mkcp" })
-- [[ DomainSocket部分 ]]--
o = s:option(Value, option_name("ds_path"), "Path", translate("A legal file path. This file must not exist before running."))
o:depends({ [option_name("transport")] = "ds" })
o = s:option(Value, _n("ds_path"), "Path", translate("A legal file path. This file must not exist before running."))
o:depends({ [_n("transport")] = "ds" })
-- [[ 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("aes-128-gcm")
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:depends({ [option_name("transport")] = "quic" })
o = s:option(Value, _n("quic_key"), translate("Encrypt Method") .. translate("Key"))
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
o:depends({ [option_name("transport")] = "quic" })
o:depends({ [_n("transport")] = "quic" })
-- [[ gRPC部分 ]]--
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName")
o:depends({ [option_name("transport")] = "grpc" })
o = s:option(Value, _n("grpc_serviceName"), "ServiceName")
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"
-- [[ Fallback部分 ]]--
o = s:option(Flag, option_name("fallback"), translate("Fallback"))
o:depends({ [option_name("protocol")] = "vless", [option_name("transport")] = "raw" })
o:depends({ [option_name("protocol")] = "trojan", [option_name("transport")] = "raw" })
o = s:option(Flag, _n("fallback"), translate("Fallback"))
o:depends({ [_n("protocol")] = "vless", [_n("transport")] = "raw" })
o:depends({ [_n("protocol")] = "trojan", [_n("transport")] = "raw" })
--[[
o = s:option(Value, option_name("fallback_alpn"), "Fallback alpn")
o:depends({ [option_name("fallback")] = true })
o = s:option(Value, _n("fallback_alpn"), "Fallback alpn")
o:depends({ [_n("fallback")] = true })
o = s:option(Value, option_name("fallback_path"), "Fallback path")
o:depends({ [option_name("fallback")] = true })
o = s:option(Value, _n("fallback_path"), "Fallback path")
o:depends({ [_n("fallback")] = true })
o = s:option(Value, option_name("fallback_dest"), "Fallback dest")
o:depends({ [option_name("fallback")] = true })
o = s:option(Value, _n("fallback_dest"), "Fallback dest")
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:depends({ [option_name("fallback")] = true })
o:depends({ [_n("fallback")] = true })
]]--
o = s:option(DynamicList, option_name("fallback_list"), "Fallback", translate("dest,path"))
o:depends({ [option_name("fallback")] = true })
o = s:option(DynamicList, _n("fallback_list"), "Fallback", translate("dest,path"))
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 = 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"
local nodes_table = {}
@ -370,46 +370,45 @@ for k, e in ipairs(api.get_valid_nodes()) do
end
end
o = s:option(ListValue, option_name("outbound_node"), translate("outbound node"))
o:value("nil", translate("Close"))
o = s:option(ListValue, _n("outbound_node"), translate("outbound node"))
o:value("", translate("Close"))
o:value("_socks", translate("Custom Socks"))
o:value("_http", translate("Custom HTTP"))
o:value("_iface", translate("Custom Interface"))
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:depends({ [option_name("outbound_node")] = "_socks"})
o:depends({ [option_name("outbound_node")] = "_http"})
o = s:option(Value, _n("outbound_node_address"), translate("Address (Support Domain Name)"))
o:depends({ [_n("outbound_node")] = "_socks"})
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:depends({ [option_name("outbound_node")] = "_socks"})
o:depends({ [option_name("outbound_node")] = "_http"})
o:depends({ [_n("outbound_node")] = "_socks"})
o:depends({ [_n("outbound_node")] = "_http"})
o = s:option(Value, option_name("outbound_node_username"), translate("Username"))
o:depends({ [option_name("outbound_node")] = "_socks"})
o:depends({ [option_name("outbound_node")] = "_http"})
o = s:option(Value, _n("outbound_node_username"), translate("Username"))
o:depends({ [_n("outbound_node")] = "_socks"})
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:depends({ [option_name("outbound_node")] = "_socks"})
o:depends({ [option_name("outbound_node")] = "_http"})
o:depends({ [_n("outbound_node")] = "_socks"})
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: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.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:value("debug")
o:value("info")
o:value("warning")
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)

View File

@ -14,7 +14,7 @@ local type_name = "sing-box"
local option_prefix = "singbox_"
local function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -27,7 +27,7 @@ local ss_method_list = {
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("socks", "Socks")
o:value("http", "HTTP")
@ -47,166 +47,166 @@ if singbox_tags:find("with_quic") then
end
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 = s:option(Flag, option_name("auth"), translate("Auth"))
o = s:option(Flag, _n("auth"), translate("Auth"))
o.validate = function(self, value, t)
if value and value == "1" then
local user_v = s.fields[option_name("username")] and s.fields[option_name("username")]:formvalue(t) or ""
local pass_v = s.fields[option_name("password")] and s.fields[option_name("password")]:formvalue(t) or ""
local user_v = s.fields[_n("username")] and s.fields[_n("username")]: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
return nil, translate("Username and Password must be used together!")
end
end
return value
end
o:depends({ [option_name("protocol")] = "mixed" })
o:depends({ [option_name("protocol")] = "socks" })
o:depends({ [option_name("protocol")] = "http" })
o:depends({ [_n("protocol")] = "mixed" })
o:depends({ [_n("protocol")] = "socks" })
o:depends({ [_n("protocol")] = "http" })
o = s:option(Value, option_name("username"), translate("Username"))
o:depends({ [option_name("auth")] = true })
o:depends({ [option_name("protocol")] = "naive" })
o = s:option(Value, _n("username"), translate("Username"))
o:depends({ [_n("auth")] = true })
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:depends({ [option_name("auth")] = true })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "naive" })
o:depends({ [option_name("protocol")] = "tuic" })
o:depends({ [_n("auth")] = true })
o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [_n("protocol")] = "naive" })
o:depends({ [_n("protocol")] = "tuic" })
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: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:depends({ [option_name("protocol")] = "hysteria" })
o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_obfs"), translate("Obfs Password"))
o:depends({ [option_name("protocol")] = "hysteria" })
o = s:option(Value, _n("hysteria_obfs"), translate("Obfs Password"))
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("string", translate("STRING"))
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:depends({ [option_name("protocol")] = "hysteria", [option_name("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")] = "string"})
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:depends({ [option_name("protocol")] = "hysteria" })
o = s:option(Value, _n("hysteria_recv_window_conn"), translate("QUIC stream receive window"))
o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_recv_window_client"), translate("QUIC connection receive window"))
o:depends({ [option_name("protocol")] = "hysteria" })
o = s:option(Value, _n("hysteria_recv_window_client"), translate("QUIC connection receive window"))
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: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:depends({ [option_name("protocol")] = "hysteria" })
o = s:option(Flag, _n("hysteria_disable_mtu_discovery"), translate("Disable MTU detection"))
o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, option_name("hysteria_alpn"), translate("QUIC TLS ALPN"))
o:depends({ [option_name("protocol")] = "hysteria" })
o = s:option(Value, _n("hysteria_alpn"), translate("QUIC TLS ALPN"))
o:depends({ [_n("protocol")] = "hysteria" })
end
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:value("bbr", translate("BBR"))
o:value("cubic", translate("CUBIC"))
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: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.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:depends({ [option_name("protocol")] = "tuic" })
o = s:option(Value, _n("tuic_alpn"), translate("QUIC TLS ALPN"))
o:depends({ [_n("protocol")] = "tuic" })
end
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:depends({ [option_name("protocol")] = "hysteria2" })
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, option_name("hysteria2_up_mbps"), translate("Max upload Mbps"))
o:depends({ [option_name("protocol")] = "hysteria2", [option_name("hysteria2_ignore_client_bandwidth")] = false })
o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
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:depends({ [option_name("protocol")] = "hysteria2", [option_name("hysteria2_ignore_client_bandwidth")] = false })
o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps"))
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("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:depends({ [option_name("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
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:depends({ [option_name("protocol")] = "hysteria2"})
o:depends({ [_n("protocol")] = "hysteria2"})
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("udp", "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:depends({ [option_name("protocol")] = "direct" })
o = s:option(Value, _n("d_address"), translate("Destination address"))
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: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: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"
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
o:value(api.gen_uuid(1))
end
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [option_name("protocol")] = "tuic" })
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "vless" })
o:depends({ [_n("protocol")] = "trojan" })
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:value("", translate("Disable"))
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.validate = function(self, value, t)
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 value == "1" then
local ca = s.fields[option_name("tls_certificateFile")] and s.fields[option_name("tls_certificateFile")]:formvalue(t) or ""
local key = s.fields[option_name("tls_keyFile")] and s.fields[option_name("tls_keyFile")]:formvalue(t) or ""
local ca = s.fields[_n("tls_certificateFile")] and s.fields[_n("tls_certificateFile")]:formvalue(t) or ""
local key = s.fields[_n("tls_keyFile")] and s.fields[_n("tls_keyFile")]:formvalue(t) or ""
if ca == "" or key == "" then
return nil, translate("Public key and Private key path can not be empty!")
end
@ -214,45 +214,45 @@ o.validate = function(self, value, t)
return value
end
end
o:depends({ [option_name("protocol")] = "http" })
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [_n("protocol")] = "http" })
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "vless" })
o:depends({ [_n("protocol")] = "trojan" })
if singbox_tags:find("with_reality_server") then
-- [[ REALITY部分 ]] --
o = s:option(Flag, option_name("reality"), translate("REALITY"))
o = s:option(Flag, _n("reality"), translate("REALITY"))
o.default = 0
o:depends({ [option_name("protocol")] = "http", [option_name("tls")] = true })
o:depends({ [option_name("protocol")] = "vmess", [option_name("tls")] = true })
o:depends({ [option_name("protocol")] = "vless", [option_name("tls")] = true })
o:depends({ [option_name("protocol")] = "trojan", [option_name("tls")] = true })
o:depends({ [_n("protocol")] = "http", [_n("tls")] = true })
o:depends({ [_n("protocol")] = "vmess", [_n("tls")] = true })
o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true })
o:depends({ [_n("protocol")] = "trojan", [_n("tls")] = true })
o = s:option(Value, option_name("reality_private_key"), translate("Private Key"))
o:depends({ [option_name("reality")] = true })
o = s:option(Value, _n("reality_private_key"), translate("Private Key"))
o:depends({ [_n("reality")] = true })
o = s:option(Value, option_name("reality_shortId"), translate("Short Id"))
o:depends({ [option_name("reality")] = true })
o = s:option(Value, _n("reality_shortId"), translate("Short Id"))
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: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.default = "443"
o:depends({ [option_name("reality")] = true })
o:depends({ [_n("reality")] = true })
end
-- [[ 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:depends({ [option_name("tls")] = true, [option_name("reality")] = false })
o:depends({ [option_name("protocol")] = "naive" })
o:depends({ [option_name("protocol")] = "hysteria" })
o:depends({ [option_name("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria2" })
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o:depends({ [_n("protocol")] = "naive" })
o:depends({ [_n("protocol")] = "hysteria" })
o:depends({ [_n("protocol")] = "tuic" })
o:depends({ [_n("protocol")] = "hysteria2" })
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@ -264,13 +264,13 @@ o.validate = function(self, value, t)
return nil
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:depends({ [option_name("tls")] = true, [option_name("reality")] = false })
o:depends({ [option_name("protocol")] = "naive" })
o:depends({ [option_name("protocol")] = "hysteria" })
o:depends({ [option_name("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria2" })
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o:depends({ [_n("protocol")] = "naive" })
o:depends({ [_n("protocol")] = "hysteria" })
o:depends({ [_n("protocol")] = "tuic" })
o:depends({ [_n("protocol")] = "hysteria2" })
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@ -283,19 +283,19 @@ o.validate = function(self, value, t)
end
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:depends({ [option_name("tls")] = true, [option_name("flow")] = "", [option_name("reality")] = false })
o:depends({ [option_name("protocol")] = "naive" })
o:depends({ [option_name("protocol")] = "hysteria" })
o:depends({ [option_name("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria2" })
o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
o:depends({ [_n("protocol")] = "naive" })
o:depends({ [_n("protocol")] = "hysteria" })
o:depends({ [_n("protocol")] = "tuic" })
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.rows = 5
o.wrap = "off"
o:depends({ [option_name("ech")] = true })
o:depends({ [_n("ech")] = true })
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*\n", "")
@ -305,80 +305,80 @@ if singbox_tags:find("with_ech") then
return value
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: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:depends({ [option_name("ech")] = true })
o:depends({ [_n("ech")] = true })
end
o = s:option(ListValue, option_name("transport"), translate("Transport"))
o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("tcp", "TCP")
o:value("http", "HTTP")
o:value("ws", "WebSocket")
o:value("httpupgrade", "HTTPUpgrade")
o:value("quic", "QUIC")
o:value("grpc", "gRPC")
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "vless" })
o:depends({ [_n("protocol")] = "trojan" })
-- [[ HTTP部分 ]]--
o = s:option(Value, option_name("http_host"), translate("HTTP Host"))
o:depends({ [option_name("transport")] = "http" })
o = s:option(Value, _n("http_host"), translate("HTTP Host"))
o:depends({ [_n("transport")] = "http" })
o = s:option(Value, option_name("http_path"), translate("HTTP Path"))
o:depends({ [option_name("transport")] = "http" })
o = s:option(Value, _n("http_path"), translate("HTTP Path"))
o:depends({ [_n("transport")] = "http" })
-- [[ WebSocket部分 ]]--
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
o:depends({ [option_name("transport")] = "ws" })
o = s:option(Value, _n("ws_host"), translate("WebSocket Host"))
o:depends({ [_n("transport")] = "ws" })
o = s:option(Value, option_name("ws_path"), translate("WebSocket Path"))
o:depends({ [option_name("transport")] = "ws" })
o = s:option(Value, _n("ws_path"), translate("WebSocket Path"))
o:depends({ [_n("transport")] = "ws" })
-- [[ HTTPUpgrade部分 ]]--
o = s:option(Value, option_name("httpupgrade_host"), translate("HTTPUpgrade Host"))
o:depends({ [option_name("transport")] = "httpupgrade" })
o = s:option(Value, _n("httpupgrade_host"), translate("HTTPUpgrade Host"))
o:depends({ [_n("transport")] = "httpupgrade" })
o = s:option(Value, option_name("httpupgrade_path"), translate("HTTPUpgrade Path"))
o:depends({ [option_name("transport")] = "httpupgrade" })
o = s:option(Value, _n("httpupgrade_path"), translate("HTTPUpgrade Path"))
o:depends({ [_n("transport")] = "httpupgrade" })
-- [[ gRPC部分 ]]--
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName")
o:depends({ [option_name("transport")] = "grpc" })
o = s:option(Value, _n("grpc_serviceName"), "ServiceName")
o:depends({ [_n("transport")] = "grpc" })
-- [[ Mux ]]--
o = s:option(Flag, option_name("mux"), translate("Mux"))
o = s:option(Flag, _n("mux"), translate("Mux"))
o.rmempty = false
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless", [option_name("flow")] = "" })
o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" })
o:depends({ [_n("protocol")] = "vmess" })
o:depends({ [_n("protocol")] = "vless", [_n("flow")] = "" })
o:depends({ [_n("protocol")] = "shadowsocks" })
o:depends({ [_n("protocol")] = "trojan" })
-- [[ 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: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: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: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 = 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"
local nodes_table = {}
@ -391,46 +391,45 @@ for k, e in ipairs(api.get_valid_nodes()) do
end
end
o = s:option(ListValue, option_name("outbound_node"), translate("outbound node"))
o:value("nil", translate("Close"))
o = s:option(ListValue, _n("outbound_node"), translate("outbound node"))
o:value("", translate("Close"))
o:value("_socks", translate("Custom Socks"))
o:value("_http", translate("Custom HTTP"))
o:value("_iface", translate("Custom Interface"))
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:depends({ [option_name("outbound_node")] = "_socks" })
o:depends({ [option_name("outbound_node")] = "_http" })
o = s:option(Value, _n("outbound_node_address"), translate("Address (Support Domain Name)"))
o:depends({ [_n("outbound_node")] = "_socks" })
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:depends({ [option_name("outbound_node")] = "_socks" })
o:depends({ [option_name("outbound_node")] = "_http" })
o:depends({ [_n("outbound_node")] = "_socks" })
o:depends({ [_n("outbound_node")] = "_http" })
o = s:option(Value, option_name("outbound_node_username"), translate("Username"))
o:depends({ [option_name("outbound_node")] = "_socks" })
o:depends({ [option_name("outbound_node")] = "_http" })
o = s:option(Value, _n("outbound_node_username"), translate("Username"))
o:depends({ [_n("outbound_node")] = "_socks" })
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:depends({ [option_name("outbound_node")] = "_socks" })
o:depends({ [option_name("outbound_node")] = "_http" })
o:depends({ [_n("outbound_node")] = "_socks" })
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: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.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:value("debug")
o:value("info")
o:value("warn")
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)

View File

@ -10,7 +10,7 @@ local type_name = "Socks"
local option_prefix = "socks_"
local function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -18,14 +18,14 @@ end
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 = s:option(Flag, option_name("auth"), translate("Auth"))
o = s:option(Flag, _n("auth"), translate("Auth"))
o.validate = function(self, value, t)
if value and value == "1" then
local user_v = s.fields[option_name("username")] and s.fields[option_name("username")]:formvalue(t) or ""
local pass_v = s.fields[option_name("password")] and s.fields[option_name("password")]:formvalue(t) or ""
local user_v = s.fields[_n("username")] and s.fields[_n("username")]: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
return nil, translate("Username and Password must be used together!")
end
@ -33,14 +33,14 @@ o.validate = function(self, value, t)
return value
end
o = s:option(Value, option_name("username"), translate("Username"))
o:depends({ [option_name("auth")] = true })
o = s:option(Value, _n("username"), translate("Username"))
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: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"
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 function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -24,23 +24,23 @@ local ssrust_encrypt_method_list = {
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 = s:option(Value, option_name("password"), translate("Password"))
o = s:option(Value, _n("password"), translate("Password"))
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
o = s:option(Value, option_name("timeout"), translate("Connection Timeout"))
o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger"
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 = s:option(Flag, option_name("log"), translate("Log"))
o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1"
o.rmempty = false

View File

@ -10,7 +10,7 @@ local type_name = "SS"
local option_prefix = "ss_"
local function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -27,23 +27,23 @@ local ss_encrypt_method_list = {
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 = s:option(Value, option_name("password"), translate("Password"))
o = s:option(Value, _n("password"), translate("Password"))
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
o = s:option(Value, option_name("timeout"), translate("Connection Timeout"))
o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger"
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 = s:option(Flag, option_name("log"), translate("Log"))
o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1"
o.rmempty = false

View File

@ -10,7 +10,7 @@ local type_name = "SSR"
local option_prefix = "ssr_"
local function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -37,37 +37,37 @@ local ssr_obfs_list = {
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 = s:option(Value, option_name("password"), translate("Password"))
o = s:option(Value, _n("password"), translate("Password"))
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
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
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
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.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 = s:option(Flag, option_name("udp_forward"), translate("UDP Forward"))
o = s:option(Flag, _n("udp_forward"), translate("UDP Forward"))
o.default = "1"
o.rmempty = false
o = s:option(Flag, option_name("log"), translate("Log"))
o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1"
o.rmempty = false

View File

@ -10,7 +10,7 @@ local type_name = "Trojan-Plus"
local option_prefix = "trojan_plus_"
local function option_name(name)
local function _n(name)
return option_prefix .. name
end
@ -18,15 +18,15 @@ end
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 = 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
o:value(api.gen_uuid(1))
end
o = s:option(Flag, option_name("tls"), translate("TLS"))
o = s:option(Flag, _n("tls"), translate("TLS"))
o.default = 0
o.validate = function(self, value, t)
if value then
@ -35,8 +35,8 @@ o.validate = function(self, value, t)
return nil, translate("Original Trojan only supported 'tls', please choose 'tls'.")
end
if value == "1" then
local ca = s.fields[option_name("tls_certificateFile")] and s.fields[option_name("tls_certificateFile")]:formvalue(t) or ""
local key = s.fields[option_name("tls_keyFile")] and s.fields[option_name("tls_keyFile")]:formvalue(t) or ""
local ca = s.fields[_n("tls_certificateFile")] and s.fields[_n("tls_certificateFile")]:formvalue(t) or ""
local key = s.fields[_n("tls_keyFile")] and s.fields[_n("tls_keyFile")]:formvalue(t) or ""
if ca == "" or key == "" then
return nil, translate("Public key and Private key path can not be empty!")
end
@ -45,9 +45,9 @@ o.validate = function(self, value, t)
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:depends({ [option_name("tls")] = true })
o:depends({ [_n("tls")] = true })
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@ -59,9 +59,9 @@ o.validate = function(self, value, t)
return nil
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:depends({ [option_name("tls")] = true })
o:depends({ [_n("tls")] = true })
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@ -73,36 +73,36 @@ o.validate = function(self, value, t)
return nil
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: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 = 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.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: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.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 = s:option(ListValue, option_name("loglevel"), translate("Log Level"))
o = s:option(ListValue, _n("loglevel"), translate("Log Level"))
o.default = "2"
o:value("0", "all")
o:value("1", "info")
o:value("2", "warn")
o:value("3", "error")
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)

View File

@ -364,6 +364,26 @@ function get_domain_from_url(url)
return url
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()
local show_node_info = uci_get_type("global_other", "show_node_info") or "0"
local nodes = {}

View File

@ -20,7 +20,7 @@ end
function gen_outbound(flag, node, tag, proxy_table)
local result = nil
if node and node ~= "nil" then
if node then
local node_id = node[".name"]
if tag == nil then
tag = node_id
@ -46,7 +46,7 @@ function gen_outbound(flag, node, tag, proxy_table)
"127.0.0.1", --bind
new_port, --socks port
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
}
else
if proxy_tag and proxy_tag ~= "nil" then
if proxy_tag then
node.detour = proxy_tag
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
if node.outbound_node == "_iface" and node.outbound_node_iface then
outbound = {
@ -905,7 +905,7 @@ function gen_config(var)
end
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
else
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)
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
if _node_id == "_direct" then
rule_outboundTag = "direct"
@ -976,7 +976,7 @@ function gen_config(var)
rule_outboundTag = _outbound.tag
end
end
elseif _node_id ~= "nil" then
elseif _node_id then
local _node = uci:get_all(appname, _node_id)
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.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))
end
end
@ -1476,7 +1476,7 @@ function gen_config(var)
tag = "block"
})
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"))
end
for k, v in pairs(config.outbounds[index]) do

View File

@ -48,7 +48,7 @@ end
function gen_outbound(flag, node, tag, proxy_table)
local result = nil
if node and node ~= "nil" then
if node then
local node_id = node[".name"]
if tag == nil then
tag = node_id
@ -82,7 +82,7 @@ function gen_outbound(flag, node, tag, proxy_table)
"127.0.0.1", --bind
new_port, --socks port
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 = {}
@ -95,7 +95,7 @@ function gen_outbound(flag, node, tag, proxy_table)
else
if node.flow == "xtls-rprx-vision" then
else
if proxy_tag and proxy_tag ~= "nil" then
if proxy_tag then
node.proxySettings = {
tag = proxy_tag,
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
if node.outbound_node == "_iface" and node.outbound_node_iface then
outbound = {
@ -735,7 +735,7 @@ function gen_config(var)
-- fallback node
local fallback_node_tag = nil
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
local is_new_node = true
for _, outbound in ipairs(outbounds) do
@ -784,7 +784,7 @@ function gen_config(var)
local last_insert_outbound
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
else
local preproxy_node = uci:get_all(appname, node.preproxy_node)
@ -1396,7 +1396,7 @@ function gen_config(var)
end
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"))
end
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 node_select = document.getElementsByName(dom_id)[0];
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) {
var d = global_id + "-tcp_node";
d = d.replace("cbi-", "cbid-").replace(new RegExp("-", 'g'), ".");
var dom = document.getElementsByName(d)[0];
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;
}
}
@ -117,7 +117,7 @@ local api = require "luci.passwall.api"
var dom_id = dom_id.replace("cbi-", "cbid-").replace(new RegExp("-", 'g'), ".");
var node_select = document.getElementsByName(dom_id)[0];
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);
if (v) {
node_select.title = v.text;

View File

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

View File

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

View File

@ -707,7 +707,7 @@ run_socks() {
;;
esac
eval node_${node}_socks_port=$socks_port
set_cache_var "node_${node}_socks_port" "${socks_port}"
# http to 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"
eval ${PROTO}_NODE_PORT=$port
set_cache_var "${PROTO}_NODE_PORT" "${port}"
case "$PROTO" in
UDP)
@ -856,7 +856,7 @@ run_redir() {
}
[ "$TCP_UDP" = "1" ] && {
UDP_REDIR_PORT=$local_port
UDP_NODE="nil"
unset UDP_NODE
_flag="TCP_UDP"
_args="${_args} udp_redir_port=${UDP_REDIR_PORT}"
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
@ -932,7 +932,7 @@ run_redir() {
}
[ "$TCP_UDP" = "1" ] && {
UDP_REDIR_PORT=$local_port
UDP_NODE="nil"
unset UDP_NODE
_flag="TCP_UDP"
_args="${_args} udp_redir_port=${UDP_REDIR_PORT}"
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
@ -974,7 +974,7 @@ run_redir() {
[ "$TCP_UDP" = "1" ] && {
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
UDP_REDIR_PORT=$TCP_REDIR_PORT
UDP_NODE="nil"
unset UDP_NODE
}
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
@ -989,7 +989,7 @@ run_redir() {
[ "$TCP_UDP" = "1" ] && {
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
UDP_REDIR_PORT=$TCP_REDIR_PORT
UDP_NODE="nil"
unset UDP_NODE
_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
@ -1001,7 +1001,7 @@ run_redir() {
[ "$TCP_UDP" = "1" ] && {
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
UDP_REDIR_PORT=$TCP_REDIR_PORT
UDP_NODE="nil"
unset UDP_NODE
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
@ -1023,7 +1023,7 @@ run_redir() {
[ "$TCP_UDP" = "1" ] && {
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
UDP_REDIR_PORT=$TCP_REDIR_PORT
UDP_NODE="nil"
unset UDP_NODE
_extra_param="${_extra_param} -local_udp_redir_port $local_port"
}
lua $UTIL_SS gen_config -node $node ${_extra_param} > $config_file
@ -1044,7 +1044,7 @@ run_redir() {
[ "$TCP_UDP" = "1" ] && {
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
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} -tcp_proxy_way $tcp_proxy_way"
@ -1057,7 +1057,7 @@ run_redir() {
[ "$TCP_UDP" = "1" ] && {
_flag="TCP_UDP"
UDP_REDIR_PORT=$TCP_REDIR_PORT
UDP_NODE="nil"
unset UDP_NODE
}
local _socks_tproxy=""
[ "$tcp_proxy_way" = "tproxy" ] && _socks_tproxy="1"
@ -1085,13 +1085,13 @@ run_redir() {
esac
unset tcp_node_socks_flag tcp_node_http_flag
[ "$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() {
local proto=${1}
eval node=\$${proto}_NODE
if [ "$node" != "nil" ]; then
if [ -n "$node" ]; then
TYPE=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
local config_file="${proto}.json"
local log_file="${proto}.log"
@ -1099,7 +1099,12 @@ start_redir() {
local port=$(echo $(get_new_port $current_port $proto))
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
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
[ "${proto}" = "UDP" ] && [ "$TCP_UDP" = "1" ] && return
echolog "${proto}节点没有选择或为空,不代理${proto}"
@ -1114,8 +1119,8 @@ start_socks() {
for id in $ids; do
local enabled=$(config_n_get $id enabled 0)
[ "$enabled" == "0" ] && continue
local node=$(config_n_get $id node nil)
[ "$node" == "nil" ] && continue
local node=$(config_n_get $id node)
[ -z "$node" ] && continue
local bind_local=$(config_n_get $id bind_local 0)
local bind="0.0.0.0"
[ "$bind_local" = "1" ] && bind="127.0.0.1"
@ -1206,23 +1211,41 @@ start_crontab() {
return
}
auto_on=$(config_t_get global_delay auto_on 0)
if [ "$auto_on" = "1" ]; then
time_off=$(config_t_get global_delay time_off)
time_on=$(config_t_get global_delay time_on)
time_restart=$(config_t_get global_delay time_restart)
[ -z "$time_off" -o "$time_off" != "nil" ] && {
echo "0 $time_off * * * /etc/init.d/$CONFIG stop" >>/etc/crontabs/root
echolog "配置定时任务:每天 $time_off 点关闭服务。"
}
[ -z "$time_on" -o "$time_on" != "nil" ] && {
echo "0 $time_on * * * /etc/init.d/$CONFIG start" >>/etc/crontabs/root
echolog "配置定时任务:每天 $time_on 点开启服务。"
}
[ -z "$time_restart" -o "$time_restart" != "nil" ] && {
echo "0 $time_restart * * * /etc/init.d/$CONFIG restart" >>/etc/crontabs/root
echolog "配置定时任务:每天 $time_restart 点重启服务。"
}
stop_week_mode=$(config_t_get global_delay stop_week_mode)
stop_time_mode=$(config_t_get global_delay stop_time_mode)
if [ -n "$stop_week_mode" ]; then
local t="0 $stop_time_mode * * $stop_week_mode"
[ "$stop_week_mode" = "7" ] && t="0 $stop_time_mode * * *"
if [ "$stop_week_mode" = "8" ]; then
update_loop=1
else
echo "$t /etc/init.d/$CONFIG stop > /dev/null 2>&1 &" >>/etc/crontabs/root
fi
echolog "配置定时任务:自动关闭服务。"
fi
start_week_mode=$(config_t_get global_delay start_week_mode)
start_time_mode=$(config_t_get global_delay start_time_mode)
if [ -n "$start_week_mode" ]; then
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
autoupdate=$(config_t_get global_rules auto_update)
@ -1695,198 +1718,221 @@ acl_app() {
[ ! -z "${source_list}" ] && echo -e "${source_list}" | sed '/^$/d' > ${acl_path}/source_list
use_global_config=${use_global_config:-0}
tcp_node=${tcp_node:-nil}
udp_node=${udp_node:-nil}
use_direct_list=${use_direct_list:-1}
use_proxy_list=${use_proxy_list:-1}
use_block_list=${use_block_list:-1}
use_gfw_list=${use_gfw_list:-1}
chn_list=${chn_list:-direct}
tcp_proxy_mode=${tcp_proxy_mode:-proxy}
udp_proxy_mode=${udp_proxy_mode:-proxy}
filter_proxy_ipv6=${filter_proxy_ipv6:-0}
dnsmasq_filter_proxy_ipv6=${filter_proxy_ipv6}
dns_shunt=${dns_shunt:-dnsmasq}
dns_mode=${dns_mode:-dns2socks}
remote_dns=${remote_dns:-1.1.1.1}
use_default_dns=${use_default_dns:-direct}
[ "$dns_mode" = "sing-box" ] && {
[ "$v2ray_dns_mode" = "doh" ] && remote_dns=${remote_dns_doh:-https://1.1.1.1/dns-query}
}
[ "${use_global_config}" = "1" ] && {
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_proxy_list=${use_proxy_list:-1}
use_block_list=${use_block_list:-1}
use_gfw_list=${use_gfw_list:-1}
chn_list=${chn_list:-direct}
tcp_proxy_mode=${tcp_proxy_mode:-proxy}
udp_proxy_mode=${udp_proxy_mode:-proxy}
filter_proxy_ipv6=${filter_proxy_ipv6:-0}
dnsmasq_filter_proxy_ipv6=${filter_proxy_ipv6}
dns_shunt=${dns_shunt:-dnsmasq}
dns_mode=${dns_mode:-dns2socks}
remote_dns=${remote_dns:-1.1.1.1}
use_default_dns=${use_default_dns:-direct}
[ "$dns_mode" = "sing-box" ] && {
[ "$v2ray_dns_mode" = "doh" ] && remote_dns=${remote_dns_doh:-https://1.1.1.1/dns-query}
}
fi
[ "$tcp_node" != "nil" ] && {
[ -n "$tcp_node" ] && {
local GLOBAL_TCP_NODE=$(get_cache_var "ACL_GLOBAL_TCP_node")
echolog "${GLOBAL_TCP_NODE}"
[ -n "${GLOBAL_TCP_NODE}" ] && GLOBAL_TCP_redir_port=$(get_cache_var "ACL_GLOBAL_TCP_redir_port")
if [ "$tcp_node" = "default" ]; then
tcp_node=$TCP_NODE
tcp_port=$TCP_REDIR_PORT
if [ -n "${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
echolog " - 全局节点未启用,跳过【${remarks}"
fi
else
[ "$(config_get_type $tcp_node nil)" = "nodes" ] && {
run_dns() {
local _dns_port
[ -n $1 ] && _dns_port=$1
[ -z ${_dns_port} ] && {
dns_port=$(get_new_port $(expr $dns_port + 1))
_dns_port=$dns_port
if [ "$dns_mode" = "dns2socks" ]; then
run_dns2socks flag=acl_${sid} socks_address=127.0.0.1 socks_port=$socks_port listen_address=0.0.0.0 listen_port=${_dns_port} dns=$remote_dns cache=1
elif [ "$dns_mode" = "sing-box" -o "$dns_mode" = "xray" ]; then
config_file=$TMP_ACL_PATH/${tcp_node}_SOCKS_${socks_port}_DNS.json
[ "$dns_mode" = "xray" ] && [ "$v2ray_dns_mode" = "tcp+doh" ] && remote_dns_doh=${remote_dns_doh:-https://1.1.1.1/dns-query}
local type=${dns_mode}
[ "${dns_mode}" = "sing-box" ] && type="singbox"
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
fi
eval node_${tcp_node}_$(echo -n "${remote_dns}" | md5sum | cut -d " " -f1)=${_dns_port}
}
[ "$dns_shunt" = "chinadns-ng" ] && [ -n "$(first_type chinadns-ng)" ] && {
chinadns_ng_min=2024.04.13
chinadns_ng_now=$(chinadns-ng -V | grep -i "ChinaDNS-NG " | awk '{print $2}')
if [ $(check_ver "$chinadns_ng_now" "$chinadns_ng_min") = 1 ]; then
echolog " * 注意:当前 ChinaDNS-NG 版本为[ $chinadns_ng_now ],请更新到[ $chinadns_ng_min ]或以上版本,否则 DNS 有可能无法正常工作!"
fi
[ "$filter_proxy_ipv6" = "1" ] && dnsmasq_filter_proxy_ipv6=0
chinadns_port=$(expr $chinadns_port + 1)
_china_ng_listen="127.0.0.1#${chinadns_port}"
_chinadns_local_dns=$(IFS=','; set -- $LOCAL_DNS; [ "${1%%[#:]*}" = "127.0.0.1" ] && echo "$1" || ([ -n "$2" ] && echo "$1,$2" || echo "$1"))
_direct_dns_mode=$(config_t_get global direct_dns_mode "auto")
case "${_direct_dns_mode}" in
udp)
_chinadns_local_dns=$(config_t_get global direct_dns_udp 223.5.5.5 | sed 's/:/#/g')
;;
tcp)
_chinadns_local_dns="tcp://$(config_t_get global direct_dns_tcp 223.5.5.5 | sed 's/:/#/g')"
;;
dot)
if [ "$(chinadns-ng -V | grep -i wolfssl)" != "nil" ]; then
_chinadns_local_dns=$(config_t_get global direct_dns_dot "tls://dot.pub@1.12.12.12")
fi
;;
esac
run_chinadns_ng \
_flag="$sid" \
_listen_port=${chinadns_port} \
_dns_local=${_chinadns_local_dns} \
_dns_trust=127.0.0.1#${_dns_port} \
_no_ipv6_trust=${filter_proxy_ipv6} \
_use_direct_list=${use_direct_list} \
_use_proxy_list=${use_proxy_list} \
_use_block_list=${use_block_list} \
_gfwlist=${use_gfw_list} \
_chnlist=${chn_list} \
_default_mode=${tcp_proxy_mode} \
_default_tag=${chinadns_ng_default_tag:-smart} \
_no_logic_log=1 \
_tcp_node=${tcp_node}
use_default_dns="chinadns_ng"
}
dnsmasq_port=$(get_new_port $(expr $dnsmasq_port + 1))
local dnsmasq_conf=${acl_path}/dnsmasq.conf
local dnsmasq_conf_path=${acl_path}/dnsmasq.d
lua $APP_PATH/helper_dnsmasq.lua add_rule -FLAG ${sid} -TMP_DNSMASQ_PATH ${dnsmasq_conf_path} -DNSMASQ_CONF_FILE ${dnsmasq_conf} \
-LISTEN_PORT ${dnsmasq_port} -DEFAULT_DNS $DEFAULT_DNS -LOCAL_DNS $LOCAL_DNS \
-USE_DIRECT_LIST "${use_direct_list}" -USE_PROXY_LIST "${use_proxy_list}" -USE_BLOCK_LIST "${use_block_list}" -USE_GFW_LIST "${use_gfw_list}" -CHN_LIST "${chn_list}" \
-TUN_DNS "127.0.0.1#${_dns_port}" -REMOTE_FAKEDNS 0 -USE_DEFAULT_DNS "${use_default_dns:-direct}" -CHINADNS_DNS ${_china_ng_listen:-0} \
-TCP_NODE $tcp_node -DEFAULT_PROXY_MODE ${tcp_proxy_mode} -NO_PROXY_IPV6 ${dnsmasq_filter_proxy_ipv6:-0} -NFTFLAG ${nftflag:-0} \
-NO_LOGIC_LOG 1
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}"
eval 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})
_socks_port=$(eval echo \${node_${tcp_node}_socks_port})
if [ -n "${_socks_port}" ] && [ -n "${_redir_port}" ]; then
socks_port=${_socks_port}
tcp_port=${_redir_port}
_dnsmasq_port=$(eval echo \${node_${tcp_node}_$(echo -n "${tcp_proxy_mode}${remote_dns}" | md5sum | cut -d " " -f1)})
if [ -z "${_dnsmasq_port}" ]; then
_dns_port=$(eval echo \${node_${tcp_node}_$(echo -n "${remote_dns}" | md5sum | cut -d " " -f1)})
run_dns ${_dns_port}
else
[ -n "${_dnsmasq_port}" ] && set_cache_var "ACL_${sid}_dns_port" "${_dnsmasq_port}"
fi
[ "$(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
socks_port=$(get_new_port $(expr $socks_port + 1))
eval node_${tcp_node}_socks_port=$socks_port
redir_port=$(get_new_port $(expr $redir_port + 1))
eval node_${tcp_node}_redir_port=$redir_port
tcp_port=$redir_port
local type=$(echo $(config_n_get $tcp_node type) | tr 'A-Z' 'a-z')
if [ -n "${type}" ] && ([ "${type}" = "sing-box" ] || [ "${type}" = "xray" ]); then
config_file="acl/${tcp_node}_TCP_${redir_port}.json"
_extra_param="socks_address=127.0.0.1 socks_port=$socks_port"
if [ "$dns_mode" = "sing-box" ] || [ "$dns_mode" = "xray" ]; then
run_dns() {
local _dns_port
[ -n $1 ] && _dns_port=$1
[ -z ${_dns_port} ] && {
dns_port=$(get_new_port $(expr $dns_port + 1))
_dns_port=$dns_port
config_file=$(echo $config_file | sed "s/TCP_/DNS_${_dns_port}_TCP_/g")
remote_dns_doh=${remote_dns}
dnsmasq_filter_proxy_ipv6=0
[ "$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}"
fi
[ "$udp_node" != "nil" ] && ([ "$udp_node" = "tcp" ] || [ "$udp_node" = "$tcp_node" ]) && {
config_file=$(echo $config_file | sed "s/TCP_/TCP_UDP_/g")
_extra_param="${_extra_param} udp_redir_port=$redir_port"
if [ "$dns_mode" = "dns2socks" ]; then
run_dns2socks flag=acl_${sid} socks_address=127.0.0.1 socks_port=$socks_port listen_address=0.0.0.0 listen_port=${_dns_port} dns=$remote_dns cache=1
elif [ "$dns_mode" = "sing-box" -o "$dns_mode" = "xray" ]; then
config_file=$TMP_ACL_PATH/${tcp_node}_SOCKS_${socks_port}_DNS.json
[ "$dns_mode" = "xray" ] && [ "$v2ray_dns_mode" = "tcp+doh" ] && remote_dns_doh=${remote_dns_doh:-https://1.1.1.1/dns-query}
local type=${dns_mode}
[ "${dns_mode}" = "sing-box" ] && type="singbox"
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
fi
set_cache_var "node_${tcp_node}_$(echo -n "${remote_dns}" | md5sum | cut -d " " -f1)" "${_dns_port}"
}
config_file="$TMP_PATH/$config_file"
[ "${type}" = "sing-box" ] && type="singbox"
run_${type} flag=$tcp_node node=$tcp_node tcp_redir_port=$redir_port ${_extra_param} config_file=$config_file
[ "$dns_shunt" = "chinadns-ng" ] && [ -n "$(first_type chinadns-ng)" ] && {
chinadns_ng_min=2024.04.13
chinadns_ng_now=$(chinadns-ng -V | grep -i "ChinaDNS-NG " | awk '{print $2}')
if [ $(check_ver "$chinadns_ng_now" "$chinadns_ng_min") = 1 ]; then
echolog " * 注意:当前 ChinaDNS-NG 版本为[ $chinadns_ng_now ],请更新到[ $chinadns_ng_min ]或以上版本,否则 DNS 有可能无法正常工作!"
fi
[ "$filter_proxy_ipv6" = "1" ] && dnsmasq_filter_proxy_ipv6=0
chinadns_port=$(expr $chinadns_port + 1)
_china_ng_listen="127.0.0.1#${chinadns_port}"
_chinadns_local_dns=$(IFS=','; set -- $LOCAL_DNS; [ "${1%%[#:]*}" = "127.0.0.1" ] && echo "$1" || ([ -n "$2" ] && echo "$1,$2" || echo "$1"))
_direct_dns_mode=$(config_t_get global direct_dns_mode "auto")
case "${_direct_dns_mode}" in
udp)
_chinadns_local_dns=$(config_t_get global direct_dns_udp 223.5.5.5 | sed 's/:/#/g')
;;
tcp)
_chinadns_local_dns="tcp://$(config_t_get global direct_dns_tcp 223.5.5.5 | sed 's/:/#/g')"
;;
dot)
if [ "$(chinadns-ng -V | grep -i wolfssl)" != "nil" ]; then
_chinadns_local_dns=$(config_t_get global direct_dns_dot "tls://dot.pub@1.12.12.12")
fi
;;
esac
run_chinadns_ng \
_flag="$sid" \
_listen_port=${chinadns_port} \
_dns_local=${_chinadns_local_dns} \
_dns_trust=127.0.0.1#${_dns_port} \
_no_ipv6_trust=${filter_proxy_ipv6} \
_use_direct_list=${use_direct_list} \
_use_proxy_list=${use_proxy_list} \
_use_block_list=${use_block_list} \
_gfwlist=${use_gfw_list} \
_chnlist=${chn_list} \
_default_mode=${tcp_proxy_mode} \
_default_tag=${chinadns_ng_default_tag:-smart} \
_no_logic_log=1 \
_tcp_node=${tcp_node}
use_default_dns="chinadns_ng"
}
dnsmasq_port=$(get_new_port $(expr $dnsmasq_port + 1))
local dnsmasq_conf=${acl_path}/dnsmasq.conf
local dnsmasq_conf_path=${acl_path}/dnsmasq.d
lua $APP_PATH/helper_dnsmasq.lua add_rule -FLAG ${sid} -TMP_DNSMASQ_PATH ${dnsmasq_conf_path} -DNSMASQ_CONF_FILE ${dnsmasq_conf} \
-LISTEN_PORT ${dnsmasq_port} -DEFAULT_DNS $DEFAULT_DNS -LOCAL_DNS $LOCAL_DNS \
-USE_DIRECT_LIST "${use_direct_list}" -USE_PROXY_LIST "${use_proxy_list}" -USE_BLOCK_LIST "${use_block_list}" -USE_GFW_LIST "${use_gfw_list}" -CHN_LIST "${chn_list}" \
-TUN_DNS "127.0.0.1#${_dns_port}" -REMOTE_FAKEDNS 0 -USE_DEFAULT_DNS "${use_default_dns:-direct}" -CHINADNS_DNS ${_china_ng_listen:-0} \
-TCP_NODE $tcp_node -DEFAULT_PROXY_MODE ${tcp_proxy_mode} -NO_PROXY_IPV6 ${dnsmasq_filter_proxy_ipv6:-0} -NFTFLAG ${nftflag:-0} \
-NO_LOGIC_LOG 1
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 "node_${tcp_node}_$(echo -n "${tcp_proxy_mode}${remote_dns}" | md5sum | cut -d " " -f1)" "${dnsmasq_port}"
}
_redir_port=$(get_cache_var "node_${tcp_node}_redir_port")
_socks_port=$(get_cache_var "node_${tcp_node}_socks_port")
if [ -n "${_socks_port}" ] && [ -n "${_redir_port}" ]; then
socks_port=${_socks_port}
tcp_port=${_redir_port}
_dnsmasq_port=$(get_cache_var "node_${tcp_node}_$(echo -n "${tcp_proxy_mode}${remote_dns}" | md5sum | cut -d " " -f1)")
if [ -z "${_dnsmasq_port}" ]; then
_dns_port=$(get_cache_var "node_${tcp_node}_$(echo -n "${remote_dns}" | md5sum | cut -d " " -f1)")
run_dns ${_dns_port}
else
[ -n "${_dnsmasq_port}" ] && set_cache_var "ACL_${sid}_dns_port" "${_dnsmasq_port}"
fi
else
config_file="acl/${tcp_node}_SOCKS_${socks_port}.json"
run_socks flag=$tcp_node node=$tcp_node bind=127.0.0.1 socks_port=$socks_port config_file=$config_file
local log_file=$TMP_ACL_PATH/ipt2socks_${tcp_node}_${redir_port}.log
log_file="/dev/null"
run_ipt2socks flag=acl_${tcp_node} tcp_tproxy=${is_tproxy} local_port=$redir_port socks_address=127.0.0.1 socks_port=$socks_port log_file=$log_file
socks_port=$(get_new_port $(expr $socks_port + 1))
set_cache_var "node_${tcp_node}_socks_port" "${socks_port}"
redir_port=$(get_new_port $(expr $redir_port + 1))
set_cache_var "node_${tcp_node}_redir_port" "${redir_port}"
tcp_port=$redir_port
local type=$(echo $(config_n_get $tcp_node type) | tr 'A-Z' 'a-z')
if [ -n "${type}" ] && ([ "${type}" = "sing-box" ] || [ "${type}" = "xray" ]); then
config_file="acl/${tcp_node}_TCP_${redir_port}.json"
_extra_param="socks_address=127.0.0.1 socks_port=$socks_port"
if [ "$dns_mode" = "sing-box" ] || [ "$dns_mode" = "xray" ]; then
dns_port=$(get_new_port $(expr $dns_port + 1))
_dns_port=$dns_port
config_file=$(echo $config_file | sed "s/TCP_/DNS_${_dns_port}_TCP_/g")
remote_dns_doh=${remote_dns}
dnsmasq_filter_proxy_ipv6=0
[ "$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}"
fi
[ -n "$udp_node" ] && ([ "$udp_node" = "tcp" ] || [ "$udp_node" = "$tcp_node" ]) && {
config_file=$(echo $config_file | sed "s/TCP_/TCP_UDP_/g")
_extra_param="${_extra_param} udp_redir_port=$redir_port"
}
config_file="$TMP_PATH/$config_file"
[ "${type}" = "sing-box" ] && type="singbox"
run_${type} flag=$tcp_node node=$tcp_node tcp_redir_port=$redir_port ${_extra_param} config_file=$config_file
else
config_file="acl/${tcp_node}_SOCKS_${socks_port}.json"
run_socks flag=$tcp_node node=$tcp_node bind=127.0.0.1 socks_port=$socks_port config_file=$config_file
local log_file=$TMP_ACL_PATH/ipt2socks_${tcp_node}_${redir_port}.log
log_file="/dev/null"
run_ipt2socks flag=acl_${tcp_node} tcp_tproxy=${is_tproxy} local_port=$redir_port socks_address=127.0.0.1 socks_port=$socks_port log_file=$log_file
fi
run_dns ${_dns_port}
fi
run_dns ${_dns_port}
set_cache_var "ACL_${sid}_tcp_node" "${tcp_node}"
set_cache_var "ACL_${sid}_tcp_redir_port" "${redir_port}"
fi
set_cache_var "ACL_${sid}_tcp_node" "${tcp_node}"
}
fi
set_cache_var "ACL_${sid}_tcp_port" "${tcp_port}"
}
[ "$udp_node" != "nil" ] && {
[ "$udp_node" = "tcp" ] && udp_node=$tcp_node
[ -n "$udp_node" ] && {
if [ "$udp_node" = "default" ]; then
if [ "$TCP_UDP" = "0" ] && [ "$UDP_NODE" = "nil" ]; then
udp_node="nil"
unset udp_port
elif [ "$TCP_UDP" = "1" ] && [ "$udp_node" = "nil" ]; then
udp_node=$TCP_NODE
udp_port=$TCP_REDIR_PORT
local GLOBAL_UDP_NODE=$(get_cache_var "ACL_GLOBAL_UDP_node")
[ -n "${GLOBAL_UDP_NODE}" ] && GLOBAL_UDP_redir_port=$(get_cache_var "ACL_GLOBAL_UDP_redir_port")
if [ -n "${GLOBAL_UDP_NODE}" ]; then
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
udp_node=$UDP_NODE
udp_port=$UDP_REDIR_PORT
echolog " - 全局节点未启用,跳过【${remarks}"
fi
elif [ "$udp_node" = "$tcp_node" ]; then
udp_node=$tcp_node
udp_port=$tcp_port
elif [ "$udp_node" = "tcp" ]; then
udp_node=$(get_cache_var "ACL_${sid}_tcp_node")
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
[ "$(config_get_type $udp_node nil)" = "nodes" ] && {
if [ "$udp_node" = "$UDP_NODE" ]; then
udp_port=$UDP_REDIR_PORT
[ "$(config_get_type $udp_node)" = "nodes" ] && {
if [ -n "${GLOBAL_UDP_NODE}" ] && [ "$udp_node" = "${GLOBAL_UDP_NODE}" ]; then
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
_redir_port=$(eval echo \${node_${udp_node}_redir_port})
_socks_port=$(eval echo \${node_${udp_node}_socks_port})
_redir_port=$(get_cache_var "node_${udp_node}_redir_port")
_socks_port=$(get_cache_var "node_${udp_node}_socks_port")
if [ -n "${_socks_port}" ] && [ -n "${_redir_port}" ]; then
socks_port=${_socks_port}
udp_port=${_redir_port}
else
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))
eval node_${udp_node}_redir_port=$redir_port
set_cache_var "node_${udp_node}_redir_port" "${redir_port}"
udp_port=$redir_port
local type=$(echo $(config_n_get $udp_node type) | tr 'A-Z' 'a-z')
@ -1904,12 +1950,12 @@ acl_app() {
fi
fi
set_cache_var "ACL_${sid}_udp_node" "${udp_node}"
set_cache_var "ACL_${sid}_udp_redir_port" "${redir_port}"
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 _china_ng_listen _chinadns_local_dns _direct_dns_mode chinadns_ng_default_tag dnsmasq_filter_proxy_ipv6
done
@ -2013,9 +2059,9 @@ stop() {
ENABLED=$(config_t_get global enabled 0)
SOCKS_ENABLED=$(config_t_get global socks_enabled 0)
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_NODE=$(config_t_get global udp_node nil)
UDP_NODE=$(config_t_get global udp_node)
TCP_UDP=0
if [ "$UDP_NODE" == "tcp" ]; then
UDP_NODE=$TCP_NODE
@ -2024,8 +2070,8 @@ elif [ "$UDP_NODE" == "$TCP_NODE" ]; then
TCP_UDP=1
fi
[ "$ENABLED" == 1 ] && {
[ "$TCP_NODE" != "nil" ] && [ "$(config_get_type $TCP_NODE nil)" != "nil" ] && ENABLED_DEFAULT_ACL=1
[ "$UDP_NODE" != "nil" ] && [ "$(config_get_type $UDP_NODE nil)" != "nil" ] && ENABLED_DEFAULT_ACL=1
[ -n "$TCP_NODE" ] && [ "$(config_get_type $TCP_NODE)" == "nodes" ] && 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" == 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 default_node_id = t["default_node"] or "_direct"
uci:foreach(appname, "shunt_rules", function(s)
local _node_id = t[s[".name"]] or "nil"
if _node_id ~= "nil" and _node_id ~= "_blackhole" then
local _node_id = t[s[".name"]]
if _node_id and _node_id ~= "_blackhole" then
if _node_id == "_default" then
_node_id = default_node_id
end

View File

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

View File

@ -198,8 +198,6 @@ load_acl() {
udp_proxy_drop_ports=${udp_proxy_drop_ports:-default}
tcp_redir_ports=${tcp_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_proxy_list=${use_proxy_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
[ -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}_tcp_port")" ] && tcp_port=$(get_cache_var "ACL_${sid}_tcp_port")
[ -n "$(get_cache_var "ACL_${sid}_udp_port")" ] && udp_port=$(get_cache_var "ACL_${sid}_udp_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}_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_udp=0
[ "$tcp_node" != "nil" ] && {
tcp_node_remark=$(config_n_get $tcp_node remarks)
[ "$(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
}
[ -n "$tcp_node" ] && [ "$(config_n_get $tcp_node protocol)" = "_shunt" ] && use_shunt_tcp=1
[ -n "$udp_node" ] && [ "$(config_n_get $udp_node protocol)" = "_shunt" ] && use_shunt_udp=1
[ "${use_global_config}" = "1" ] && {
tcp_node_remark=$(config_n_get $TCP_NODE remarks)
@ -503,7 +493,7 @@ load_acl() {
local DNS_REDIRECT
[ $(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}
else
[ -n "${DIRECT_DNSMASQ_PORT}" ] && DNS_REDIRECT=${DIRECT_DNSMASQ_PORT}
@ -566,7 +556,7 @@ load_acl() {
# 加载TCP默认代理模式
if [ -n "${TCP_PROXY_MODE}" ]; then
[ "$TCP_NODE" != "nil" ] && {
[ -n "$TCP_NODE" ] && {
msg2="${msg}使用 TCP 节点[$(config_n_get $TCP_NODE remarks)]"
if [ -n "${is_tproxy}" ]; then
msg2="${msg2}(TPROXY:${TCP_REDIR_PORT})"
@ -619,7 +609,7 @@ load_acl() {
# 加载UDP默认代理模式
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})"
$ipt_m -A PSW $(comment "默认") -p udp -d $FAKE_IP -j PSW_RULE
@ -686,7 +676,7 @@ filter_server_port() {
filter_node() {
local node=${1}
local stream=${2}
if [ -n "$node" ] && [ "$node" != "nil" ]; then
if [ -n "$node" ]; then
local address=$(config_n_get $node address)
local port=$(config_n_get $node port)
[ -z "$address" ] && [ -z "$port" ] && {
@ -736,12 +726,12 @@ add_firewall_rule() {
local USE_PROXY_LIST_ALL=${USE_PROXY_LIST}
local USE_DIRECT_LIST_ALL=${USE_DIRECT_LIST}
local USE_BLOCK_LIST_ALL=${USE_BLOCK_LIST}
local _TCP_NODE=$(config_t_get global tcp_node nil)
local _UDP_NODE=$(config_t_get global udp_node nil)
local _TCP_NODE=$(config_t_get global tcp_node)
local _UDP_NODE=$(config_t_get global udp_node)
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
[ "$_UDP_NODE" != "nil" ] && [ "$(config_n_get $_UDP_NODE protocol)" = "_shunt" ] && USE_SHUNT_UDP=1 && USE_SHUNT_NODE=1
[ -n "$_TCP_NODE" ] && [ "$(config_n_get $_TCP_NODE protocol)" = "_shunt" ] && USE_SHUNT_TCP=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
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 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 ] && {
local ipt_tmp=$ipt_n
@ -1046,7 +1036,7 @@ add_firewall_rule() {
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" ] && {
$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
@ -1078,7 +1068,7 @@ add_firewall_rule() {
}
# 加载路由器自身代理 TCP
if [ "$TCP_NODE" != "nil" ]; then
if [ -n "$TCP_NODE" ]; then
_proxy_tcp_access() {
[ -n "${2}" ] || return 0
if echo "${2}" | grep -q -v ':'; then
@ -1156,7 +1146,7 @@ add_firewall_rule() {
fi
# 加载路由器自身代理 UDP
if [ "$UDP_NODE" != "nil" -o "$TCP_UDP" = "1" ]; then
if [ -n "$UDP_NODE" -o "$TCP_UDP" = "1" ]; then
_proxy_udp_access() {
[ -n "${2}" ] || return 0
if echo "${2}" | grep -q -v ':'; then

View File

@ -258,8 +258,6 @@ load_acl() {
udp_proxy_drop_ports=${udp_proxy_drop_ports:-default}
tcp_redir_ports=${tcp_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_proxy_list=${use_proxy_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
[ -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}_tcp_port")" ] && tcp_port=$(get_cache_var "ACL_${sid}_tcp_port")
[ -n "$(get_cache_var "ACL_${sid}_udp_port")" ] && udp_port=$(get_cache_var "ACL_${sid}_udp_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}_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_udp=0
[ "$tcp_node" != "nil" ] && {
tcp_node_remark=$(config_n_get $tcp_node remarks)
[ "$(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
}
[ -n "$tcp_node" ] && [ "$(config_n_get $tcp_node protocol)" = "_shunt" ] && use_shunt_tcp=1
[ -n "$udp_node" ] && [ "$(config_n_get $udp_node protocol)" = "_shunt" ] && use_shunt_udp=1
[ "${use_global_config}" = "1" ] && {
tcp_node_remark=$(config_n_get $TCP_NODE remarks)
@ -556,7 +546,7 @@ load_acl() {
local DNS_REDIRECT
[ $(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}
else
[ -n "${DIRECT_DNSMASQ_PORT}" ] && DNS_REDIRECT=${DIRECT_DNSMASQ_PORT}
@ -621,7 +611,7 @@ load_acl() {
# 加载TCP默认代理模式
if [ -n "${TCP_PROXY_MODE}" ]; then
[ "$TCP_NODE" != "nil" ] && {
[ -n "$TCP_NODE" ] && {
msg2="${msg}使用 TCP 节点[$(config_n_get $TCP_NODE remarks)]"
if [ -n "${is_tproxy}" ]; then
msg2="${msg2}(TPROXY:${TCP_REDIR_PORT})"
@ -679,7 +669,7 @@ load_acl() {
# 加载UDP默认代理模式
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})"
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() {
local node=${1}
local stream=${2}
if [ -n "$node" ] && [ "$node" != "nil" ]; then
if [ -n "$node" ]; then
local address=$(config_n_get $node address)
local port=$(config_n_get $node port)
[ -z "$address" ] && [ -z "$port" ] && {
@ -811,12 +801,12 @@ add_firewall_rule() {
local USE_PROXY_LIST_ALL=${USE_PROXY_LIST}
local USE_DIRECT_LIST_ALL=${USE_DIRECT_LIST}
local USE_BLOCK_LIST_ALL=${USE_BLOCK_LIST}
local _TCP_NODE=$(config_t_get global tcp_node nil)
local _UDP_NODE=$(config_t_get global udp_node nil)
local _TCP_NODE=$(config_t_get global tcp_node)
local _UDP_NODE=$(config_t_get global udp_node)
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
[ "$_UDP_NODE" != "nil" ] && [ "$(config_n_get $_UDP_NODE protocol)" = "_shunt" ] && USE_SHUNT_UDP=1 && USE_SHUNT_NODE=1
[ -n "$_TCP_NODE" ] && [ "$(config_n_get $_TCP_NODE protocol)" = "_shunt" ] && USE_SHUNT_TCP=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
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
}
[ "$TCP_UDP" = "1" ] && [ "$UDP_NODE" = "nil" ] && UDP_NODE=$TCP_NODE
[ "$TCP_UDP" = "1" ] && [ -z "$UDP_NODE" ] && UDP_NODE=$TCP_NODE
[ "$ENABLED_DEFAULT_ACL" == 1 ] && {
msg="【路由器本机】,"
@ -1104,7 +1094,7 @@ add_firewall_rule() {
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" ] && {
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\""
@ -1136,7 +1126,7 @@ add_firewall_rule() {
}
# 加载路由器自身代理 TCP
if [ "$TCP_NODE" != "nil" ]; then
if [ -n "$TCP_NODE" ]; then
_proxy_tcp_access() {
[ -n "${2}" ] || return 0
if echo "${2}" | grep -q -v ':'; then
@ -1219,7 +1209,7 @@ add_firewall_rule() {
fi
# 加载路由器自身代理 UDP
if [ "$UDP_NODE" != "nil" -o "$TCP_UDP" = "1" ]; then
if [ -n "$UDP_NODE" -o "$TCP_UDP" = "1" ]; then
_proxy_udp_access() {
[ -n "${2}" ] || return 0
if echo "${2}" | grep -q -v ':'; then

View File

@ -61,8 +61,8 @@ test_proxy() {
test_node() {
local node_id=$1
local _type=$(echo $(config_n_get ${node_id} type nil) | tr 'A-Z' 'a-z')
[ "${_type}" != "nil" ] && {
local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z')
[ -n "${_type}" ] && {
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
local curlx="socks5h://127.0.0.1:${_tmp_port}"
@ -101,7 +101,7 @@ test_auto_switch() {
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}
[ $? -eq 0 ] && {
#主节点正常,切换到主节点
@ -159,7 +159,7 @@ start() {
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_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)
delay=$(config_n_get $id autoswitch_testing_time 30)
sleep 5s
@ -167,8 +167,8 @@ start() {
retry_num=$(config_n_get $id autoswitch_retry_num 1)
restore_switch=$(config_n_get $id autoswitch_restore_switch 0)
probe_url=$(config_n_get $id autoswitch_probe_url "https://www.google.com/generate_204")
backup_node=$(config_n_get $id autoswitch_backup_node nil)
while [ -n "$backup_node" -a "$backup_node" != "nil" ]; do
backup_node=$(config_n_get $id autoswitch_backup_node)
while [ -n "$backup_node" ]; do
[ -f "$LOCK_FILE" ] && {
sleep 6s
continue

View File

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

View File

@ -30,6 +30,33 @@ do
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)
weekupdate=$(config_t_get global_rules week_update)
hourupdate=$(config_t_get global_rules interval_update)

View File

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

View File

@ -20,7 +20,7 @@ index 2b72468..15c6437 100644
define Package/$(PKG_NAME)/postrm
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
+++ b/luci-app-passwall/luasrc/controller/passwall.lua
@@ -279,7 +279,7 @@ function connect_status()
@ -33,10 +33,10 @@ index 33c5319..6ddcdfd 100644
if code ~= 0 then
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
index 488cd50..541167f 100644
index 7ea652a..2b4c853 100644
--- a/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("208.67.220.220", "208.67.220.220 (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="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
index 8348217..19b16b7 100644
index 551c824..2a6a814 100644
--- a/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
option auto_on '0'
option start_daemon '1'
- option start_delay '60'
+ option start_delay '15'