diff --git a/luci-app-passwall2/Makefile b/luci-app-passwall2/Makefile index 574fbadba..a0d6932b7 100644 --- a/luci-app-passwall2/Makefile +++ b/luci-app-passwall2/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall2 -PKG_VERSION:=1.19-3 +PKG_VERSION:=1.19-4 PKG_RELEASE:= PKG_CONFIG_DEPENDS:= \ diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/rule.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/rule.lua index af3768ab4..56ce0fcf9 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/rule.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/rule.lua @@ -6,6 +6,20 @@ m = Map(appname) s = m:section(TypedSection, "global_rules", translate("Rule status")) s.anonymous = true +o = s:option(Value, "v2ray_location_asset", translate("Location of V2ray/Xray asset"), translate("This variable specifies a directory where geoip.dat and geosite.dat files are.")) +o.default = "/usr/share/v2ray/" +o.rmempty = false + +---- Custom geo file url +o = s:option(Value, "geoip_url", translate("Custom geoip URL")) +o.default = "https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases/latest" +o.rmempty = false + +o = s:option(Value, "geosite_url", translate("Custom geosite URL")) +o.default = "https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases/latest" +o.rmempty = false +---- + s:append(Template(appname .. "/rule/rule_version")) ---- Auto Update @@ -27,20 +41,6 @@ for e = 0, 23 do o:value(e, e .. translate("oclock")) end o.default = 0 o:depends("auto_update", true) -o = s:option(Value, "v2ray_location_asset", translate("Location of V2ray/Xray asset"), translate("This variable specifies a directory where geoip.dat and geosite.dat files are.")) -o.default = "/usr/share/v2ray/" -o.rmempty = false - ----- Custom geo file url -o = s:option(Value, "geoip_url", translate("Custom geoip URL")) -o.default = "https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases/latest" -o.rmempty = false - -o = s:option(Value, "geosite_url", translate("Custom geosite URL")) -o.default = "https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases/latest" -o.rmempty = false ----- - s = m:section(TypedSection, "shunt_rules", "V2ray/Xray " .. translate("Shunt Rule"), "" .. translate("Please note attention to the priority, the higher the order, the higher the priority.") .. "") s.template = "cbi/tblsection" s.anonymous = false diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/brook.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/brook.lua index ad5a42a33..8dc46bc29 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/brook.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/brook.lua @@ -6,6 +6,8 @@ if not api.is_finded("brook") then return end +local type_name = "Brook" + local option_prefix = "brook_" local function option_name(name) @@ -18,32 +20,41 @@ local function rm_prefix_cfgvalue(self, section) end end local function rm_prefix_write(self, section, value) - if self.option:find(option_prefix) == 1 then - m:set(section, self.option:sub(1 + #option_prefix), value) + if s.fields["type"]:formvalue(arg[1]) == type_name then + if self.option:find(option_prefix) == 1 then + m:set(section, self.option:sub(1 + #option_prefix), value) + end + end +end +local function rm_prefix_remove(self, section, value) + if s.fields["type"]:formvalue(arg[1]) == type_name then + if self.option:find(option_prefix) == 1 then + m:del(section, self.option:sub(1 + #option_prefix)) + end end end -- [[ Brook ]] -s.fields["type"]:value("Brook", translate("Brook")) +s.fields["type"]:value(type_name, translate("Brook")) -o = s:option(ListValue, "brook_protocol", translate("Protocol")) +o = s:option(ListValue, option_name("protocol"), translate("Protocol")) o:value("client", translate("Brook")) o:value("wsclient", translate("WebSocket")) -o = s:option(Value, "brook_address", translate("Address (Support Domain Name)")) +o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) -o = s:option(Value, "brook_port", translate("Port")) +o = s:option(Value, option_name("port"), translate("Port")) o.datatype = "port" -o = s:option(Value, "brook_ws_path", translate("WebSocket Path")) +o = s:option(Value, option_name("ws_path"), translate("WebSocket Path")) o.placeholder = "/" -o:depends({ brook_protocol = "wsclient" }) +o:depends({ [option_name("protocol")] = "wsclient" }) -o = s:option(Flag, "brook_tls", translate("Use TLS")) -o:depends({ brook_protocol = "wsclient" }) +o = s:option(Flag, option_name("tls"), translate("Use TLS")) +o:depends({ [option_name("protocol")] = "wsclient" }) -o = s:option(Value, "brook_password", translate("Password")) +o = s:option(Value, option_name("password"), translate("Password")) o.password = true for key, value in pairs(s.fields) do @@ -51,15 +62,16 @@ for key, value in pairs(s.fields) do if not s.fields[key].not_rewrite then s.fields[key].cfgvalue = rm_prefix_cfgvalue s.fields[key].write = rm_prefix_write + s.fields[key].remove = rm_prefix_remove end local deps = s.fields[key].deps if #deps > 0 then for index, value in ipairs(deps) do - deps[index]["type"] = "Brook" + deps[index]["type"] = type_name end else - s.fields[key]:depends({ type = "Brook" }) + s.fields[key]:depends({ type = type_name }) end end end diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/hysteria.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/hysteria.lua index e1ed3bd9d..0ae9c2023 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/hysteria.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/hysteria.lua @@ -6,6 +6,8 @@ if not api.is_finded("hysteria") then return end +local type_name = "Hysteria" + local option_prefix = "hysteria_" local function option_name(name) @@ -18,82 +20,90 @@ local function rm_prefix_cfgvalue(self, section) end end local function rm_prefix_write(self, section, value) - if self.option:find(option_prefix) == 1 then - m:set(section, self.option:sub(1 + #option_prefix), value) + if s.fields["type"]:formvalue(arg[1]) == type_name then + if self.option:find(option_prefix) == 1 then + m:set(section, self.option:sub(1 + #option_prefix), value) + end + end +end +local function rm_prefix_remove(self, section, value) + if s.fields["type"]:formvalue(arg[1]) == type_name then + if self.option:find(option_prefix) == 1 then + m:del(section, self.option:sub(1 + #option_prefix)) + end end end -- [[ Hysteria ]] -s.fields["type"]:value("Hysteria", translate("Hysteria")) +s.fields["type"]:value(type_name, translate("Hysteria")) -o = s:option(ListValue, "hysteria_protocol", translate("Protocol")) +o = s:option(ListValue, option_name("protocol"), translate("Protocol")) o:value("udp", "UDP") o:value("faketcp", "faketcp") o:value("wechat-video", "wechat-video") -o = s:option(Value, "hysteria_address", translate("Address (Support Domain Name)")) +o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) -o = s:option(Value, "hysteria_port", translate("Port")) +o = s:option(Value, option_name("port"), translate("Port")) o.datatype = "port" -o = s:option(Value, "hysteria_hop", translate("Additional ports for hysteria hop")) -o:depends("type", "Hysteria") +o = s:option(Value, option_name("hop"), translate("Additional ports for hysteria hop")) o.not_rewrite = true -o = s:option(Value, "hysteria_obfs", translate("Obfs Password")) +o = s:option(Value, option_name("obfs"), translate("Obfs Password")) o.not_rewrite = true -o = s:option(ListValue, "hysteria_auth_type", translate("Auth Type")) +o = s:option(ListValue, option_name("auth_type"), translate("Auth Type")) o:value("disable", translate("Disable")) o:value("string", translate("STRING")) o:value("base64", translate("BASE64")) o.not_rewrite = true -o = s:option(Value, "hysteria_auth_password", translate("Auth Password")) +o = s:option(Value, option_name("auth_password"), translate("Auth Password")) o.password = true -o:depends({ hysteria_auth_type = "string"}) -o:depends({ hysteria_auth_type = "base64"}) +o:depends({ [option_name("auth_type")] = "string"}) +o:depends({ [option_name("auth_type")] = "base64"}) o.not_rewrite = true -o = s:option(Value, "hysteria_alpn", translate("QUIC TLS ALPN")) +o = s:option(Value, option_name("alpn"), translate("QUIC TLS ALPN")) o.not_rewrite = true -o = s:option(Flag, "hysteria_fast_open", translate("Fast Open")) +o = s:option(Flag, option_name("fast_open"), translate("Fast Open")) o.default = "0" -o = s:option(Value, "hysteria_tls_serverName", translate("Domain")) +o = s:option(Value, option_name("tls_serverName"), translate("Domain")) -o = s:option(Flag, "hysteria_tls_allowInsecure", translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) +o = s:option(Flag, option_name("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) o.default = "0" -o = s:option(Value, "hysteria_up_mbps", translate("Max upload Mbps")) +o = s:option(Value, option_name("up_mbps"), translate("Max upload Mbps")) o.default = "10" o.not_rewrite = true -o = s:option(Value, "hysteria_down_mbps", translate("Max download Mbps")) +o = s:option(Value, option_name("down_mbps"), translate("Max download Mbps")) o.default = "50" o.not_rewrite = true -o = s:option(Value, "hysteria_recv_window_conn", translate("QUIC stream receive window")) +o = s:option(Value, option_name("recv_window_conn"), translate("QUIC stream receive window")) o.not_rewrite = true -o = s:option(Value, "hysteria_recv_window", translate("QUIC connection receive window")) +o = s:option(Value, option_name("recv_window"), translate("QUIC connection receive window")) o.not_rewrite = true -o = s:option(Value, "hysteria_handshake_timeout", translate("Handshake Timeout")) +o = s:option(Value, option_name("handshake_timeout"), translate("Handshake Timeout")) o.not_rewrite = true -o = s:option(Value, "hysteria_idle_timeout", translate("Idle Timeout")) +o = s:option(Value, option_name("idle_timeout"), translate("Idle Timeout")) o.not_rewrite = true -o = s:option(Value, "hysteria_hop_interval", translate("Hop Interval")) +o = s:option(Value, option_name("hop_interval"), translate("Hop Interval")) o.not_rewrite = true -o = s:option(Flag, "hysteria_disable_mtu_discovery", translate("Disable MTU detection")) +o = s:option(Flag, option_name("disable_mtu_discovery"), translate("Disable MTU detection")) o.not_rewrite = true -o = s:option(Flag, "hysteria_lazy_start", translate("Lazy Start")) +o = s:option(Flag, option_name("lazy_start"), translate("Lazy Start")) o.not_rewrite = true for key, value in pairs(s.fields) do @@ -101,15 +111,16 @@ for key, value in pairs(s.fields) do if not s.fields[key].not_rewrite then s.fields[key].cfgvalue = rm_prefix_cfgvalue s.fields[key].write = rm_prefix_write + s.fields[key].remove = rm_prefix_remove end local deps = s.fields[key].deps if #deps > 0 then for index, value in ipairs(deps) do - deps[index]["type"] = "Hysteria" + deps[index]["type"] = type_name end else - s.fields[key]:depends({ type = "Hysteria" }) + s.fields[key]:depends({ type = type_name }) end end end diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/naive.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/naive.lua index 3390eb270..d0a2d10e8 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/naive.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/naive.lua @@ -6,6 +6,8 @@ if not api.is_finded("naive") then return end +local type_name = "Naiveproxy" + local option_prefix = "naive_" local function option_name(name) @@ -18,27 +20,36 @@ local function rm_prefix_cfgvalue(self, section) end end local function rm_prefix_write(self, section, value) - if self.option:find(option_prefix) == 1 then - m:set(section, self.option:sub(1 + #option_prefix), value) + if s.fields["type"]:formvalue(arg[1]) == type_name then + if self.option:find(option_prefix) == 1 then + m:set(section, self.option:sub(1 + #option_prefix), value) + end + end +end +local function rm_prefix_remove(self, section, value) + if s.fields["type"]:formvalue(arg[1]) == type_name then + if self.option:find(option_prefix) == 1 then + m:del(section, self.option:sub(1 + #option_prefix)) + end end end -- [[ Naive ]] -s.fields["type"]:value("Naiveproxy", translate("NaiveProxy")) +s.fields["type"]:value(type_name, translate("NaiveProxy")) -o = s:option(ListValue, "naive_protocol", translate("Protocol")) +o = s:option(ListValue, option_name("protocol"), translate("Protocol")) o:value("https", translate("HTTPS")) o:value("quic", translate("QUIC")) -o = s:option(Value, "naive_address", translate("Address (Support Domain Name)")) +o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) -o = s:option(Value, "naive_port", translate("Port")) +o = s:option(Value, option_name("port"), translate("Port")) o.datatype = "port" -o = s:option(Value, "naive_username", translate("Username")) +o = s:option(Value, option_name("username"), translate("Username")) -o = s:option(Value, "naive_password", translate("Password")) +o = s:option(Value, option_name("password"), translate("Password")) o.password = true for key, value in pairs(s.fields) do @@ -46,15 +57,16 @@ for key, value in pairs(s.fields) do if not s.fields[key].not_rewrite then s.fields[key].cfgvalue = rm_prefix_cfgvalue s.fields[key].write = rm_prefix_write + s.fields[key].remove = rm_prefix_remove end local deps = s.fields[key].deps if #deps > 0 then for index, value in ipairs(deps) do - deps[index]["type"] = "Naiveproxy" + deps[index]["type"] = type_name end else - s.fields[key]:depends({ type = "Naiveproxy" }) + s.fields[key]:depends({ type = type_name }) end end end diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua index 83fa7e5ec..c8e082b23 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua @@ -21,13 +21,17 @@ local function rm_prefix_cfgvalue(self, section) end end local function rm_prefix_write(self, section, value) - if self.option:find(option_prefix) == 1 then - m:set(section, self.option:sub(1 + #option_prefix), value) + if s.fields["type"]:formvalue(arg[1]) == "Xray" or s.fields["type"]:formvalue(arg[1]) == "V2ray" then + if self.option:find(option_prefix) == 1 then + m:set(section, self.option:sub(1 + #option_prefix), value) + end end end local function rm_prefix_remove(self, section, value) - if self.option:find(option_prefix) == 1 then - m:del(section, self.option:sub(1 + #option_prefix)) + if s.fields["type"]:formvalue(arg[1]) == "Xray" or s.fields["type"]:formvalue(arg[1]) == "V2ray" then + if self.option:find(option_prefix) == 1 then + m:del(section, self.option:sub(1 + #option_prefix)) + end end end @@ -82,7 +86,7 @@ if api.is_finded("v2ray") then s.fields["type"]:value("V2ray", translate("V2ray")) end -o = s:option(ListValue, "xray_protocol", translate("Protocol")) +o = s:option(ListValue, option_name("protocol"), translate("Protocol")) o:value("vmess", translate("Vmess")) o:value("vless", translate("VLESS")) o:value("http", translate("HTTP")) @@ -95,14 +99,10 @@ o:value("_shunt", translate("Shunt")) o:value("_iface", translate("Custom Interface") .. " (Only Support Xray)") add_xray_depends(o) add_v2ray_depends(o) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write -o = s:option(Value, "xray_iface", translate("Interface")) +o = s:option(Value, option_name("iface"), translate("Interface")) o.default = "eth1" -add_xray_depends(o, { xray_protocol = "_iface" }) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write +o:depends({ [option_name("protocol")] = "_iface" }) local nodes_table = {} local balancers_table = {} @@ -129,54 +129,45 @@ for k, e in ipairs(api.get_valid_nodes()) do end -- 负载均衡列表 -local o = s:option(DynamicList, "xray_balancing_node", translate("Load balancing node list"), translate("Load balancing node list, document")) -add_xray_depends(o, { xray_protocol = "_balancing" }) -add_v2ray_depends(o, { xray_protocol = "_balancing" }) +local o = s:option(DynamicList, option_name("balancing_node"), translate("Load balancing node list"), translate("Load balancing node list, document")) +o:depends({ [option_name("protocol")] = "_balancing" }) +add_v2ray_depends(o, { [option_name("protocol")] = "_balancing" }) for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write -local o = s:option(ListValue, "xray_balancingStrategy", translate("Balancing Strategy")) -add_xray_depends(o, { xray_protocol = "_balancing" }) -add_v2ray_depends(o, { xray_protocol = "_balancing" }) +local o = s:option(ListValue, option_name("balancingStrategy"), translate("Balancing Strategy")) +add_xray_depends(o, { [option_name("protocol")] = "_balancing" }) +add_v2ray_depends(o, { [option_name("protocol")] = "_balancing" }) o:value("random") o:value("leastPing") o.default = "random" -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write -- 探测地址 -local o = s:option(Flag, "xray_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.")) -add_xray_depends(o, { xray_balancingStrategy = "leastPing" }) -add_v2ray_depends(o, { xray_balancingStrategy = "leastPing" }) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write +local o = 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.")) +add_xray_depends(o, { [option_name("balancingStrategy")] = "leastPing" }) +add_v2ray_depends(o, { [option_name("balancingStrategy")] = "leastPing" }) -local o = s:option(Value, "xray_probeUrl", translate("Probe URL")) -add_xray_depends(o, { xray_useCustomProbeUrl = true }) -add_v2ray_depends(o, { xray_useCustomProbeUrl = true }) +local o = s:option(Value, option_name("probeUrl"), translate("Probe URL")) +add_xray_depends(o, { [option_name("useCustomProbeUrl")] = true }) +add_v2ray_depends(o, { [option_name("useCustomProbeUrl")] = true }) o.default = "https://www.google.com/generate_204" o.description = translate("The URL used to detect the connection status.") -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write -- 探测间隔 -local o = s:option(Value, "xray_probeInterval", translate("Probe Interval")) -add_xray_depends(o, { xray_balancingStrategy = "leastPing" }) -add_v2ray_depends(o, { xray_balancingStrategy = "leastPing" }) +local o = s:option(Value, option_name("probeInterval"), translate("Probe Interval")) +add_xray_depends(o, { [option_name("balancingStrategy")] = "leastPing" }) +add_v2ray_depends(o, { [option_name("balancingStrategy")] = "leastPing" }) o.default = "1m" o.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 ns, us, ms, s, m, h, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.") -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write -- [[ 分流模块 ]] if #nodes_table > 0 then - o = s:option(Flag, "preproxy_enabled", translate("Preproxy")) - add_xray_depends(o, { xray_protocol = "_shunt" }) - add_v2ray_depends(o, { xray_protocol = "_shunt" }) - o = s:option(Value, "main_node", string.format('%s', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including Default) has a separate switch that controls whether this rule uses the pre-proxy or not.")) - add_xray_depends(o, { xray_protocol = "_shunt", preproxy_enabled = true }) - add_v2ray_depends(o, { xray_protocol = "_shunt", preproxy_enabled = true }) + o = s:option(Flag, option_name("preproxy_enabled"), translate("Preproxy")) + o:depends({ [option_name("protocol")] = "_shunt" }) + add_v2ray_depends(o, { [option_name("protocol")] = "_shunt" }) + + o = s:option(Value, option_name("main_node"), string.format('%s', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including Default) has a separate switch that controls whether this rule uses the pre-proxy or not.")) + o:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true }) + add_v2ray_depends(o, { [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true }) for k, v in pairs(balancers_table) do o:value(v.id, v.remarks) end @@ -190,13 +181,13 @@ if #nodes_table > 0 then end uci:foreach(appname, "shunt_rules", function(e) if e[".name"] and e.remarks then - o = s:option(Value, e[".name"], string.format('* %s', api.url("shunt_rules", e[".name"]), e.remarks)) + o = s:option(Value, option_name(e[".name"]), string.format('* %s', api.url("shunt_rules", e[".name"]), e.remarks)) o:value("nil", translate("Close")) o:value("_default", translate("Default")) o:value("_direct", translate("Direct Connection")) o:value("_blackhole", translate("Blackhole")) - add_xray_depends(o, { xray_protocol = "_shunt" }) - add_v2ray_depends(o, { xray_protocol = "_shunt" }) + o:depends({ [option_name("protocol")] = "_shunt" }) + add_v2ray_depends(o, { [option_name("protocol")] = "_shunt" }) if #nodes_table > 0 then for k, v in pairs(balancers_table) do @@ -205,28 +196,29 @@ uci:foreach(appname, "shunt_rules", function(e) for k, v in pairs(iface_table) do o:value(v.id, v.remarks) end - local pt = s:option(ListValue, e[".name"] .. "_proxy_tag", string.format('* %s', e.remarks .. " " .. translate("Preproxy"))) + local pt = s:option(ListValue, option_name(e[".name"] .. "_proxy_tag"), string.format('* %s', e.remarks .. " " .. translate("Preproxy"))) pt:value("nil", translate("Close")) pt:value("main", translate("Preproxy Node")) pt.default = "nil" for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) - add_xray_depends(pt, { xray_protocol = "_shunt", preproxy_enabled = "1", [e[".name"]] = v.id }) - add_v2ray_depends(pt, { xray_protocol = "_shunt", preproxy_enabled = "1", [e[".name"]] = v.id }) + pt:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true, [option_name(e[".name"])] = v.id }) + add_v2ray_depends(o, { [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true, [option_name(e[".name"])] = v.id }) end end end end) -o = s:option(DummyValue, "shunt_tips", " ") +o = s:option(DummyValue, option_name("shunt_tips"), " ") +o.not_rewrite = true o.rawhtml = true o.cfgvalue = function(t, n) return string.format('%s', translate("No shunt rules? Click me to go to add.")) end -add_xray_depends(o, { xray_protocol = "_shunt" }) +o:depends({ [option_name("protocol")] = "_shunt" }) -local o = s:option(Value, "default_node", string.format('* %s', translate("Default"))) -add_xray_depends(o, { xray_protocol = "_shunt" }) +local o = s:option(Value, option_name("default_node"), string.format('* %s', translate("Default"))) +o:depends({ [option_name("protocol")] = "_shunt" }) o:value("_direct", translate("Direct Connection")) o:value("_blackhole", translate("Blackhole")) @@ -237,17 +229,17 @@ if #nodes_table > 0 then for k, v in pairs(iface_table) do o:value(v.id, v.remarks) end - local dpt = s:option(ListValue, "default_proxy_tag", string.format('* %s', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node.")) + local dpt = s:option(ListValue, option_name("default_proxy_tag"), string.format('* %s', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node.")) dpt:value("nil", translate("Close")) dpt:value("main", translate("Preproxy Node")) dpt.default = "nil" for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) - add_xray_depends(dpt, { xray_protocol = "_shunt", preproxy_enabled = "1", default_node = v.id }) + dpt:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true, [option_name("default_node")] = v.id }) end end -o = s:option(ListValue, "domainStrategy", translate("Domain Strategy")) +o = s:option(ListValue, option_name("domainStrategy"), translate("Domain Strategy")) o:value("AsIs") o:value("IPIfNonMatch") o:value("IPOnDemand") @@ -256,182 +248,170 @@ o.description = "
" -add_xray_depends(o, { xray_protocol = "_shunt" }) +o:depends({ [option_name("protocol")] = "_shunt" }) -o = s:option(ListValue, "domainMatcher", translate("Domain matcher")) +o = s:option(ListValue, option_name("domainMatcher"), translate("Domain matcher")) o:value("hybrid") o:value("linear") -add_xray_depends(o, { xray_protocol = "_shunt" }) +o:depends({ [option_name("protocol")] = "_shunt" }) -- [[ 分流模块 End ]] -o = s:option(Value, "xray_address", translate("Address (Support Domain Name)")) -add_xray_depends(o, { xray_protocol = "vmess" }) -add_xray_depends(o, { xray_protocol = "vless" }) -add_xray_depends(o, { xray_protocol = "http" }) -add_xray_depends(o, { xray_protocol = "socks" }) -add_xray_depends(o, { xray_protocol = "shadowsocks" }) -add_xray_depends(o, { xray_protocol = "trojan" }) -add_xray_depends(o, { xray_protocol = "wireguard" }) -add_v2ray_depends(o, { xray_protocol = "vmess" }) -add_v2ray_depends(o, { xray_protocol = "vless" }) -add_v2ray_depends(o, { xray_protocol = "http" }) -add_v2ray_depends(o, { xray_protocol = "socks" }) -add_v2ray_depends(o, { xray_protocol = "shadowsocks" }) -add_v2ray_depends(o, { xray_protocol = "trojan" }) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write +o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) +add_xray_depends(o, { [option_name("protocol")] = "vmess" }) +add_xray_depends(o, { [option_name("protocol")] = "vless" }) +add_xray_depends(o, { [option_name("protocol")] = "http" }) +add_xray_depends(o, { [option_name("protocol")] = "socks" }) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" }) +add_xray_depends(o, { [option_name("protocol")] = "trojan" }) +add_xray_depends(o, { [option_name("protocol")] = "wireguard" }) +add_v2ray_depends(o, { [option_name("protocol")] = "vmess" }) +add_v2ray_depends(o, { [option_name("protocol")] = "vless" }) +add_v2ray_depends(o, { [option_name("protocol")] = "http" }) +add_v2ray_depends(o, { [option_name("protocol")] = "socks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "trojan" }) -o = s:option(Value, "xray_port", translate("Port")) +o = s:option(Value, option_name("port"), translate("Port")) o.datatype = "port" -add_xray_depends(o, { xray_protocol = "vmess" }) -add_xray_depends(o, { xray_protocol = "vless" }) -add_xray_depends(o, { xray_protocol = "http" }) -add_xray_depends(o, { xray_protocol = "socks" }) -add_xray_depends(o, { xray_protocol = "shadowsocks" }) -add_xray_depends(o, { xray_protocol = "trojan" }) -add_xray_depends(o, { xray_protocol = "wireguard" }) -add_v2ray_depends(o, { xray_protocol = "vmess" }) -add_v2ray_depends(o, { xray_protocol = "vless" }) -add_v2ray_depends(o, { xray_protocol = "http" }) -add_v2ray_depends(o, { xray_protocol = "socks" }) -add_v2ray_depends(o, { xray_protocol = "shadowsocks" }) -add_v2ray_depends(o, { xray_protocol = "trojan" }) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write +add_xray_depends(o, { [option_name("protocol")] = "vmess" }) +add_xray_depends(o, { [option_name("protocol")] = "vless" }) +add_xray_depends(o, { [option_name("protocol")] = "http" }) +add_xray_depends(o, { [option_name("protocol")] = "socks" }) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" }) +add_xray_depends(o, { [option_name("protocol")] = "trojan" }) +add_xray_depends(o, { [option_name("protocol")] = "wireguard" }) +add_v2ray_depends(o, { [option_name("protocol")] = "vmess" }) +add_v2ray_depends(o, { [option_name("protocol")] = "vless" }) +add_v2ray_depends(o, { [option_name("protocol")] = "http" }) +add_v2ray_depends(o, { [option_name("protocol")] = "socks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "trojan" }) -o = s:option(Value, "xray_username", translate("Username")) -add_xray_depends(o, { xray_protocol = "http" }) -add_xray_depends(o, { xray_protocol = "socks" }) -add_v2ray_depends(o, { xray_protocol = "http" }) -add_v2ray_depends(o, { xray_protocol = "socks" }) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write +o = s:option(Value, option_name("username"), translate("Username")) +add_xray_depends(o, { [option_name("protocol")] = "http" }) +add_xray_depends(o, { [option_name("protocol")] = "socks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "http" }) +add_v2ray_depends(o, { [option_name("protocol")] = "socks" }) -o = s:option(Value, "xray_password", translate("Password")) +o = s:option(Value, option_name("password"), translate("Password")) o.password = true -add_xray_depends(o, { xray_protocol = "http" }) -add_xray_depends(o, { xray_protocol = "socks" }) -add_xray_depends(o, { xray_protocol = "shadowsocks" }) -add_xray_depends(o, { xray_protocol = "trojan" }) -add_v2ray_depends(o, { xray_protocol = "http" }) -add_v2ray_depends(o, { xray_protocol = "socks" }) -add_v2ray_depends(o, { xray_protocol = "shadowsocks" }) -add_v2ray_depends(o, { xray_protocol = "trojan" }) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write +add_xray_depends(o, { [option_name("protocol")] = "http" }) +add_xray_depends(o, { [option_name("protocol")] = "socks" }) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" }) +add_xray_depends(o, { [option_name("protocol")] = "trojan" }) +add_v2ray_depends(o, { [option_name("protocol")] = "http" }) +add_v2ray_depends(o, { [option_name("protocol")] = "socks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "trojan" }) -o = s:option(ListValue, "security", translate("Encrypt Method")) +o = s:option(ListValue, option_name("security"), translate("Encrypt Method")) for a, t in ipairs(security_list) do o:value(t) end -add_xray_depends(o, { xray_protocol = "vmess" }) -add_v2ray_depends(o, { xray_protocol = "vmess" }) +add_xray_depends(o, { [option_name("protocol")] = "vmess" }) +add_v2ray_depends(o, { [option_name("protocol")] = "vmess" }) -o = s:option(Value, "encryption", translate("Encrypt Method")) +o = s:option(Value, option_name("encryption"), translate("Encrypt Method")) o.default = "none" o:value("none") -add_xray_depends(o, { xray_protocol = "vless" }) -add_v2ray_depends(o, { xray_protocol = "vless" }) +add_xray_depends(o, { [option_name("protocol")] = "vless" }) +add_v2ray_depends(o, { [option_name("protocol")] = "vless" }) o = s:option(ListValue, "v_ss_encrypt_method", translate("Encrypt Method")) +o.not_rewrite = true for a, t in ipairs(v_ss_encrypt_method_list) do o:value(t) end -add_v2ray_depends(o, { xray_protocol = "shadowsocks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" }) function o.cfgvalue(self, section) return m:get(section, "method") end function o.write(self, section, value) - m:set(section, "method", value) + if s.fields["type"]:formvalue(arg[1]) == "Xray" or s.fields["type"]:formvalue(arg[1]) == "V2ray" then + m:set(section, "method", value) + end end -o = s:option(ListValue, "x_ss_encrypt_method", translate("Encrypt Method")) +o = s:option(ListValue, option_name("x_ss_encrypt_method"), translate("Encrypt Method")) +o.not_rewrite = true for a, t in ipairs(x_ss_encrypt_method_list) do o:value(t) end -add_xray_depends(o, { xray_protocol = "shadowsocks" }) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" }) function o.cfgvalue(self, section) return m:get(section, "method") end function o.write(self, section, value) - m:set(section, "method", value) + if s.fields["type"]:formvalue(arg[1]) == "Xray" or s.fields["type"]:formvalue(arg[1]) == "V2ray" then + m:set(section, "method", value) + end end -o = s:option(Flag, "iv_check", translate("IV Check")) -add_v2ray_depends(o, { xray_protocol = "shadowsocks" }) -add_xray_depends(o, { xray_protocol = "shadowsocks", x_ss_encrypt_method = "aes-128-gcm" }) -add_xray_depends(o, { xray_protocol = "shadowsocks", x_ss_encrypt_method = "aes-256-gcm" }) -add_xray_depends(o, { xray_protocol = "shadowsocks", x_ss_encrypt_method = "chacha20-poly1305" }) -add_xray_depends(o, { xray_protocol = "shadowsocks", x_ss_encrypt_method = "xchacha20-poly1305" }) +o = s:option(Flag, option_name("iv_check"), translate("IV Check")) +add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" }) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "aes-128-gcm" }) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "aes-256-gcm" }) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "chacha20-poly1305" }) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "xchacha20-poly1305" }) -o = s:option(Flag, "uot", translate("UDP over TCP"), translate("Need Xray-core or sing-box as server side.")) -add_xray_depends(o, { xray_protocol = "shadowsocks", x_ss_encrypt_method = "2022-blake3-aes-128-gcm" }) -add_xray_depends(o, { xray_protocol = "shadowsocks", x_ss_encrypt_method = "2022-blake3-aes-256-gcm" }) -add_xray_depends(o, { xray_protocol = "shadowsocks", x_ss_encrypt_method = "2022-blake3-chacha20-poly1305" }) +o = s:option(Flag, option_name("uot"), translate("UDP over TCP"), translate("Need Xray-core or sing-box as server side.")) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "2022-blake3-aes-128-gcm" }) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "2022-blake3-aes-256-gcm" }) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "2022-blake3-chacha20-poly1305" }) -o = s:option(Value, "xray_uuid", translate("ID")) +o = s:option(Value, option_name("uuid"), translate("ID")) o.password = true -add_xray_depends(o, { xray_protocol = "vmess" }) -add_xray_depends(o, { xray_protocol = "vless" }) -add_v2ray_depends(o, { xray_protocol = "vmess" }) -add_v2ray_depends(o, { xray_protocol = "vless" }) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write +add_xray_depends(o, { [option_name("protocol")] = "vmess" }) +add_xray_depends(o, { [option_name("protocol")] = "vless" }) +add_v2ray_depends(o, { [option_name("protocol")] = "vmess" }) +add_v2ray_depends(o, { [option_name("protocol")] = "vless" }) -o = s:option(Flag, "xray_tls", translate("TLS")) +o = s:option(Flag, option_name("tls"), translate("TLS")) o.default = 0 -add_xray_depends(o, { xray_protocol = "vmess" }) -add_xray_depends(o, { xray_protocol = "vless" }) -add_xray_depends(o, { xray_protocol = "socks" }) -add_xray_depends(o, { xray_protocol = "trojan" }) -add_xray_depends(o, { xray_protocol = "shadowsocks" }) -add_v2ray_depends(o, { xray_protocol = "vmess" }) -add_v2ray_depends(o, { xray_protocol = "vless" }) -add_v2ray_depends(o, { xray_protocol = "socks" }) -add_v2ray_depends(o, { xray_protocol = "trojan" }) -add_v2ray_depends(o, { xray_protocol = "shadowsocks" }) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write +add_xray_depends(o, { [option_name("protocol")] = "vmess" }) +add_xray_depends(o, { [option_name("protocol")] = "vless" }) +add_xray_depends(o, { [option_name("protocol")] = "socks" }) +add_xray_depends(o, { [option_name("protocol")] = "trojan" }) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "vmess" }) +add_v2ray_depends(o, { [option_name("protocol")] = "vless" }) +add_v2ray_depends(o, { [option_name("protocol")] = "socks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "trojan" }) +add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" }) -o = s:option(Value, "xray_tlsflow", translate("flow")) +o = s:option(Value, option_name("tlsflow"), translate("flow")) o.default = "" o:value("", translate("Disable")) o:value("xtls-rprx-vision") o:value("xtls-rprx-vision-udp443") -add_xray_depends(o, { xray_protocol = "vless", xray_tls = true, transport = "tcp" }) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write +add_xray_depends(o, { [option_name("protocol")] = "vless", [option_name("tls")] = true, [option_name("transport")] = "tcp" }) -o = s:option(Flag, "reality", translate("REALITY"), translate("Only recommend to use with VLESS-TCP-XTLS-Vision.")) +o = s:option(Flag, option_name("reality"), translate("REALITY"), translate("Only recommend to use with VLESS-TCP-XTLS-Vision.")) o.default = 0 -add_xray_depends(o, { xray_tls = true, transport = "tcp" }) -add_xray_depends(o, { xray_tls = true, transport = "h2" }) -add_xray_depends(o, { xray_tls = true, transport = "grpc" }) +add_xray_depends(o, { [option_name("tls")] = true, [option_name("transport")] = "tcp" }) +add_xray_depends(o, { [option_name("tls")] = true, [option_name("transport")] = "h2" }) +add_xray_depends(o, { [option_name("tls")] = true, [option_name("transport")] = "grpc" }) -o = s:option(ListValue, "alpn", translate("alpn")) +o = s:option(ListValue, option_name("alpn"), translate("alpn")) o.default = "default" o:value("default", translate("Default")) o:value("h2,http/1.1") o:value("h2") o:value("http/1.1") -add_xray_depends(o, { xray_tls = true, reality = false }) -add_v2ray_depends(o, { xray_tls = true }) +add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = false }) +add_v2ray_depends(o, { [option_name("tls")] = true }) --- o = s:option(Value, "minversion", translate("minversion")) +-- o = s:option(Value, option_name("minversion"), translate("minversion")) -- o.default = "1.3" -- o:value("1.3") --- add_xray_depends(o, { xray_tls = true }) --- add_v2ray_depends(o, { xray_tls = true }) +-- add_xray_depends(o, { [option_name("tls")] = true }) +-- add_v2ray_depends(o, { [option_name("tls")] = true }) -o = s:option(Value, "xray_tls_serverName", translate("Domain")) -add_xray_depends(o, { xray_tls = true }) -add_v2ray_depends(o, { xray_tls = true }) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write +o = s:option(Value, option_name("tls_serverName"), translate("Domain")) +add_xray_depends(o, { [option_name("tls")] = true }) +add_v2ray_depends(o, { [option_name("tls")] = true }) -o = s:option(Flag, "xray_tls_allowInsecure", translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) +o = s:option(Flag, option_name("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) o.default = "0" -add_xray_depends(o, { xray_tls = true, reality = false }) -add_v2ray_depends(o, { xray_tls = true }) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write +add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = false }) +add_v2ray_depends(o, { [option_name("tls")] = true }) -o = s:option(Value, "xray_fingerprint", translate("Finger Print"), translate("Avoid using randomized, unless you have to.")) +o = s:option(Value, option_name("fingerprint"), translate("Finger Print"), translate("Avoid using randomized, unless you have to.")) o:value("", translate("Disable")) o:value("chrome") o:value("firefox") @@ -444,23 +424,21 @@ o:value("qq") o:value("random") o:value("randomized") o.default = "" -add_xray_depends(o, { xray_tls = true, reality = false }) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write -o.remove = rm_prefix_remove +add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = false }) -- [[ REALITY部分 ]] -- -o = s:option(Value, "reality_publicKey", translate("Public Key")) -add_xray_depends(o, { xray_tls = true, reality = true }) +o = s:option(Value, option_name("reality_publicKey"), translate("Public Key")) +add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = true }) -o = s:option(Value, "reality_shortId", translate("Short Id")) -add_xray_depends(o, { xray_tls = true, reality = true }) +o = s:option(Value, option_name("reality_shortId"), translate("Short Id")) +add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = true }) -o = s:option(Value, "reality_spiderX", translate("Spider X")) +o = s:option(Value, option_name("reality_spiderX"), translate("Spider X")) o.placeholder = "/" -add_xray_depends(o, { xray_tls = true, reality = true }) +add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = true }) -o = s:option(Value, "reality_fingerprint", translate("Finger Print"), translate("Avoid using randomized, unless you have to.")) +o = s:option(Value, option_name("reality_fingerprint"), translate("Finger Print"), translate("Avoid using randomized, unless you have to.")) +o.not_rewrite = true o:value("chrome") o:value("firefox") o:value("safari") @@ -472,15 +450,17 @@ o:value("qq") o:value("random") o:value("randomized") o.default = "chrome" -add_xray_depends(o, { xray_tls = true, reality = true }) +add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = true }) function o.cfgvalue(self, section) return m:get(section, "fingerprint") end function o.write(self, section, value) - m:set(section, "fingerprint", value) + if s.fields["type"]:formvalue(arg[1]) == "Xray" or s.fields["type"]:formvalue(arg[1]) == "V2ray" then + m:set(section, "fingerprint", value) + end end -o = s:option(ListValue, "transport", translate("Transport")) +o = s:option(ListValue, option_name("transport"), translate("Transport")) o:value("tcp", "TCP") o:value("mkcp", "mKCP") o:value("ws", "WebSocket") @@ -488,254 +468,252 @@ o:value("h2", "HTTP/2") o:value("ds", "DomainSocket") o:value("quic", "QUIC") o:value("grpc", "gRPC") -add_xray_depends(o, { xray_protocol = "vmess" }) -add_xray_depends(o, { xray_protocol = "vless" }) -add_xray_depends(o, { xray_protocol = "socks" }) -add_xray_depends(o, { xray_protocol = "shadowsocks" }) -add_xray_depends(o, { xray_protocol = "trojan" }) -add_v2ray_depends(o, { xray_protocol = "vmess" }) -add_v2ray_depends(o, { xray_protocol = "vless" }) -add_v2ray_depends(o, { xray_protocol = "socks" }) -add_v2ray_depends(o, { xray_protocol = "shadowsocks" }) -add_v2ray_depends(o, { xray_protocol = "trojan" }) +add_xray_depends(o, { [option_name("protocol")] = "vmess" }) +add_xray_depends(o, { [option_name("protocol")] = "vless" }) +add_xray_depends(o, { [option_name("protocol")] = "socks" }) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" }) +add_xray_depends(o, { [option_name("protocol")] = "trojan" }) +add_v2ray_depends(o, { [option_name("protocol")] = "vmess" }) +add_v2ray_depends(o, { [option_name("protocol")] = "vless" }) +add_v2ray_depends(o, { [option_name("protocol")] = "socks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "trojan" }) --[[ -o = s:option(ListValue, "ss_transport", translate("Transport")) +o = s:option(ListValue, option_name("ss_transport"), translate("Transport")) o:value("ws", "WebSocket") o:value("h2", "HTTP/2") o:value("h2+ws", "HTTP/2 & WebSocket") -add_xray_depends(o, { xray_protocol = "shadowsocks" }) -add_v2ray_depends(o, { xray_protocol = "shadowsocks" }) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" }) ]]-- -o = s:option(Value, "wireguard_public_key", translate("Public Key")) -add_xray_depends(o, { xray_protocol = "wireguard" }) +o = s:option(Value, option_name("wireguard_public_key"), translate("Public Key")) +add_xray_depends(o, { [option_name("protocol")] = "wireguard" }) -o = s:option(Value, "wireguard_secret_key", translate("Private Key")) -add_xray_depends(o, { xray_protocol = "wireguard" }) +o = s:option(Value, option_name("wireguard_secret_key"), translate("Private Key")) +add_xray_depends(o, { [option_name("protocol")] = "wireguard" }) -o = s:option(Value, "wireguard_preSharedKey", translate("Pre shared key")) -add_xray_depends(o, { xray_protocol = "wireguard" }) +o = s:option(Value, option_name("wireguard_preSharedKey"), translate("Pre shared key")) +add_xray_depends(o, { [option_name("protocol")] = "wireguard" }) -o = s:option(DynamicList, "wireguard_local_address", translate("Local Address")) -add_xray_depends(o, { xray_protocol = "wireguard" }) +o = s:option(DynamicList, option_name("wireguard_local_address"), translate("Local Address")) +add_xray_depends(o, { [option_name("protocol")] = "wireguard" }) -o = s:option(Value, "wireguard_mtu", translate("MTU")) +o = s:option(Value, option_name("wireguard_mtu"), translate("MTU")) o.default = "1420" -add_xray_depends(o, { xray_protocol = "wireguard" }) +add_xray_depends(o, { [option_name("protocol")] = "wireguard" }) if api.compare_versions(api.get_app_version("xray"), ">=", "1.8.0") then - o = s:option(Value, "wireguard_reserved", translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings.")) - add_xray_depends(o, { xray_protocol = "wireguard" }) + o = s:option(Value, option_name("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings.")) + add_xray_depends(o, { [option_name("protocol")] = "wireguard" }) end -o = s:option(Value, "wireguard_keepAlive", translate("Keep Alive")) +o = s:option(Value, option_name("wireguard_keepAlive"), translate("Keep Alive")) o.default = "0" -add_xray_depends(o, { xray_protocol = "wireguard" }) +add_xray_depends(o, { [option_name("protocol")] = "wireguard" }) -- [[ TCP部分 ]]-- -- TCP伪装 -o = s:option(ListValue, "tcp_guise", translate("Camouflage Type")) +o = s:option(ListValue, option_name("tcp_guise"), translate("Camouflage Type")) o:value("none", "none") o:value("http", "http") -add_xray_depends(o, { transport = "tcp" }) -add_v2ray_depends(o, { transport = "tcp" }) +add_xray_depends(o, { [option_name("transport")] = "tcp" }) +add_v2ray_depends(o, { [option_name("transport")] = "tcp" }) -- HTTP域名 -o = s:option(DynamicList, "tcp_guise_http_host", translate("HTTP Host")) -add_xray_depends(o, { tcp_guise = "http" }) -add_v2ray_depends(o, { tcp_guise = "http" }) +o = s:option(DynamicList, option_name("tcp_guise_http_host"), translate("HTTP Host")) +add_xray_depends(o, { [option_name("tcp_guise")] = "http" }) +add_v2ray_depends(o, { [option_name("tcp_guise")] = "http" }) -- HTTP路径 -o = s:option(DynamicList, "tcp_guise_http_path", translate("HTTP Path")) +o = s:option(DynamicList, option_name("tcp_guise_http_path"), translate("HTTP Path")) o.placeholder = "/" -add_xray_depends(o, { tcp_guise = "http" }) -add_v2ray_depends(o, { tcp_guise = "http" }) +add_xray_depends(o, { [option_name("tcp_guise")] = "http" }) +add_v2ray_depends(o, { [option_name("tcp_guise")] = "http" }) -- [[ mKCP部分 ]]-- -o = s:option(ListValue, "mkcp_guise", translate("Camouflage Type"), translate('
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)')) +o = s:option(ListValue, option_name("mkcp_guise"), translate("Camouflage Type"), translate('
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)')) for a, t in ipairs(header_type_list) do o:value(t) end -add_xray_depends(o, { transport = "mkcp" }) -add_v2ray_depends(o, { transport = "mkcp" }) +add_xray_depends(o, { [option_name("transport")] = "mkcp" }) +add_v2ray_depends(o, { [option_name("transport")] = "mkcp" }) -o = s:option(Value, "mkcp_mtu", translate("KCP MTU")) +o = s:option(Value, option_name("mkcp_mtu"), translate("KCP MTU")) o.default = "1350" -add_xray_depends(o, { transport = "mkcp" }) -add_v2ray_depends(o, { transport = "mkcp" }) +add_xray_depends(o, { [option_name("transport")] = "mkcp" }) +add_v2ray_depends(o, { [option_name("transport")] = "mkcp" }) -o = s:option(Value, "mkcp_tti", translate("KCP TTI")) +o = s:option(Value, option_name("mkcp_tti"), translate("KCP TTI")) o.default = "20" -add_xray_depends(o, { transport = "mkcp" }) -add_v2ray_depends(o, { transport = "mkcp" }) +add_xray_depends(o, { [option_name("transport")] = "mkcp" }) +add_v2ray_depends(o, { [option_name("transport")] = "mkcp" }) -o = s:option(Value, "mkcp_uplinkCapacity", translate("KCP uplinkCapacity")) +o = s:option(Value, option_name("mkcp_uplinkCapacity"), translate("KCP uplinkCapacity")) o.default = "5" -add_xray_depends(o, { transport = "mkcp" }) -add_v2ray_depends(o, { transport = "mkcp" }) +add_xray_depends(o, { [option_name("transport")] = "mkcp" }) +add_v2ray_depends(o, { [option_name("transport")] = "mkcp" }) -o = s:option(Value, "mkcp_downlinkCapacity", translate("KCP downlinkCapacity")) +o = s:option(Value, option_name("mkcp_downlinkCapacity"), translate("KCP downlinkCapacity")) o.default = "20" -add_xray_depends(o, { transport = "mkcp" }) -add_v2ray_depends(o, { transport = "mkcp" }) +add_xray_depends(o, { [option_name("transport")] = "mkcp" }) +add_v2ray_depends(o, { [option_name("transport")] = "mkcp" }) -o = s:option(Flag, "mkcp_congestion", translate("KCP Congestion")) -add_xray_depends(o, { transport = "mkcp" }) -add_v2ray_depends(o, { transport = "mkcp" }) +o = s:option(Flag, option_name("mkcp_congestion"), translate("KCP Congestion")) +add_xray_depends(o, { [option_name("transport")] = "mkcp" }) +add_v2ray_depends(o, { [option_name("transport")] = "mkcp" }) -o = s:option(Value, "mkcp_readBufferSize", translate("KCP readBufferSize")) +o = s:option(Value, option_name("mkcp_readBufferSize"), translate("KCP readBufferSize")) o.default = "1" -add_xray_depends(o, { transport = "mkcp" }) -add_v2ray_depends(o, { transport = "mkcp" }) +add_xray_depends(o, { [option_name("transport")] = "mkcp" }) +add_v2ray_depends(o, { [option_name("transport")] = "mkcp" }) -o = s:option(Value, "mkcp_writeBufferSize", translate("KCP writeBufferSize")) +o = s:option(Value, option_name("mkcp_writeBufferSize"), translate("KCP writeBufferSize")) o.default = "1" -add_xray_depends(o, { transport = "mkcp" }) -add_v2ray_depends(o, { transport = "mkcp" }) +add_xray_depends(o, { [option_name("transport")] = "mkcp" }) +add_v2ray_depends(o, { [option_name("transport")] = "mkcp" }) -o = s:option(Value, "mkcp_seed", translate("KCP Seed")) -add_xray_depends(o, { transport = "mkcp" }) -add_v2ray_depends(o, { transport = "mkcp" }) +o = s:option(Value, option_name("mkcp_seed"), translate("KCP Seed")) +add_xray_depends(o, { [option_name("transport")] = "mkcp" }) +add_v2ray_depends(o, { [option_name("transport")] = "mkcp" }) -- [[ WebSocket部分 ]]-- -o = s:option(Value, "xray_ws_host", translate("WebSocket Host")) -add_xray_depends(o, { transport = "ws" }) -add_xray_depends(o, { ss_transport = "ws" }) -add_v2ray_depends(o, { transport = "ws" }) -add_v2ray_depends(o, { ss_transport = "ws" }) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write +o = s:option(Value, option_name("ws_host"), translate("WebSocket Host")) +add_xray_depends(o, { [option_name("transport")] = "ws" }) +add_xray_depends(o, { [option_name("ss_transport")] = "ws" }) +add_v2ray_depends(o, { [option_name("transport")] = "ws" }) +add_v2ray_depends(o, { [option_name("ss_transport")] = "ws" }) -o = s:option(Value, "xray_ws_path", translate("WebSocket Path")) +o = s:option(Value, option_name("ws_path"), translate("WebSocket Path")) o.placeholder = "/" -add_xray_depends(o, { transport = "ws" }) -add_xray_depends(o, { ss_transport = "ws" }) -add_v2ray_depends(o, { transport = "ws" }) -add_v2ray_depends(o, { ss_transport = "ws" }) -o.cfgvalue = rm_prefix_cfgvalue -o.write = rm_prefix_write +add_xray_depends(o, { [option_name("transport")] = "ws" }) +add_xray_depends(o, { [option_name("ss_transport")] = "ws" }) +add_v2ray_depends(o, { [option_name("transport")] = "ws" }) +add_v2ray_depends(o, { [option_name("ss_transport")] = "ws" }) -o = s:option(Flag, "ws_enableEarlyData", translate("Enable early data")) -add_v2ray_depends(o, { transport = "ws" }) +o = s:option(Flag, "v2ray_ws_enableEarlyData", translate("Enable early data")) +add_v2ray_depends(o, { [option_name("transport")] = "ws" }) -o = s:option(Value, "ws_maxEarlyData", translate("Early data length")) +o = s:option(Value, "v2ray_ws_maxEarlyData", translate("Early data length")) o.default = "1024" -add_v2ray_depends(o, { ws_enableEarlyData = true }) +add_v2ray_depends(o, { v2ray_ws_enableEarlyData = true }) -o = s:option(Value, "ws_earlyDataHeaderName", translate("Early data header name"), translate("Recommended value: Sec-WebSocket-Protocol")) -add_v2ray_depends(o, { ws_enableEarlyData = true }) +o = s:option(Value, "v2ray_ws_earlyDataHeaderName", translate("Early data header name"), translate("Recommended value: Sec-WebSocket-Protocol")) +add_v2ray_depends(o, { v2ray_ws_enableEarlyData = true }) -- [[ HTTP/2部分 ]]-- -o = s:option(Value, "xray_h2_host", translate("HTTP/2 Host")) -add_xray_depends(o, { transport = "h2" }) -add_xray_depends(o, { ss_transport = "h2" }) -add_v2ray_depends(o, { transport = "h2" }) -add_v2ray_depends(o, { ss_transport = "h2" }) +o = s:option(Value, option_name("h2_host"), translate("HTTP/2 Host")) +add_xray_depends(o, { [option_name("transport")] = "h2" }) +add_xray_depends(o, { [option_name("ss_transport")] = "h2" }) +add_v2ray_depends(o, { [option_name("transport")] = "h2" }) +add_v2ray_depends(o, { [option_name("ss_transport")] = "h2" }) -o = s:option(Value, "xray_h2_path", translate("HTTP/2 Path")) +o = s:option(Value, option_name("h2_path"), translate("HTTP/2 Path")) o.placeholder = "/" -add_xray_depends(o, { transport = "h2" }) -add_xray_depends(o, { ss_transport = "h2" }) -add_v2ray_depends(o, { transport = "h2" }) -add_v2ray_depends(o, { ss_transport = "h2" }) +add_xray_depends(o, { [option_name("transport")] = "h2" }) +add_xray_depends(o, { [option_name("ss_transport")] = "h2" }) +add_v2ray_depends(o, { [option_name("transport")] = "h2" }) +add_v2ray_depends(o, { [option_name("ss_transport")] = "h2" }) -o = s:option(Flag, "h2_health_check", translate("Health check")) -add_xray_depends(o, { transport = "h2" }) +o = s:option(Flag, option_name("h2_health_check"), translate("Health check")) +add_xray_depends(o, { [option_name("transport")] = "h2" }) -o = s:option(Value, "h2_read_idle_timeout", translate("Idle timeout")) +o = s:option(Value, option_name("h2_read_idle_timeout"), translate("Idle timeout")) o.default = "10" -add_xray_depends(o, { h2_health_check = true }) +add_xray_depends(o, { [option_name("h2_health_check")] = true }) -o = s:option(Value, "h2_health_check_timeout", translate("Health check timeout")) +o = s:option(Value, option_name("h2_health_check_timeout"), translate("Health check timeout")) o.default = "15" -add_xray_depends(o, { h2_health_check = true }) +add_xray_depends(o, { [option_name("h2_health_check")] = true }) -- [[ DomainSocket部分 ]]-- -o = s:option(Value, "ds_path", "Path", translate("A legal file path. This file must not exist before running.")) -add_xray_depends(o, { transport = "ds" }) -add_v2ray_depends(o, { transport = "ds" }) +o = s:option(Value, option_name("ds_path"), "Path", translate("A legal file path. This file must not exist before running.")) +add_xray_depends(o, { [option_name("transport")] = "ds" }) +add_v2ray_depends(o, { [option_name("transport")] = "ds" }) -- [[ QUIC部分 ]]-- -o = s:option(ListValue, "quic_security", translate("Encrypt Method")) +o = s:option(ListValue, option_name("quic_security"), translate("Encrypt Method")) o:value("none") o:value("aes-128-gcm") o:value("chacha20-poly1305") -add_xray_depends(o, { transport = "quic" }) -add_v2ray_depends(o, { transport = "quic" }) +add_xray_depends(o, { [option_name("transport")] = "quic" }) +add_v2ray_depends(o, { [option_name("transport")] = "quic" }) -o = s:option(Value, "quic_key", translate("Encrypt Method") .. translate("Key")) -add_xray_depends(o, { transport = "quic" }) -add_v2ray_depends(o, { transport = "quic" }) +o = s:option(Value, option_name("quic_key"), translate("Encrypt Method") .. translate("Key")) +add_xray_depends(o, { [option_name("transport")] = "quic" }) +add_v2ray_depends(o, { [option_name("transport")] = "quic" }) -o = s:option(ListValue, "quic_guise", translate("Camouflage Type")) +o = s:option(ListValue, option_name("quic_guise"), translate("Camouflage Type")) for a, t in ipairs(header_type_list) do o:value(t) end -add_xray_depends(o, { transport = "quic" }) -add_v2ray_depends(o, { transport = "quic" }) +add_xray_depends(o, { [option_name("transport")] = "quic" }) +add_v2ray_depends(o, { [option_name("transport")] = "quic" }) -- [[ gRPC部分 ]]-- -o = s:option(Value, "grpc_serviceName", "ServiceName") -add_xray_depends(o, { transport = "grpc" }) -add_v2ray_depends(o, { transport = "grpc" }) +o = s:option(Value, option_name("grpc_serviceName"), "ServiceName") +add_xray_depends(o, { [option_name("transport")] = "grpc" }) +add_v2ray_depends(o, { [option_name("transport")] = "grpc" }) -o = s:option(ListValue, "grpc_mode", "gRPC " .. translate("Transfer mode")) +o = s:option(ListValue, option_name("grpc_mode"), "gRPC " .. translate("Transfer mode")) o:value("gun") o:value("multi") -add_xray_depends(o, { transport = "grpc" }) +add_xray_depends(o, { [option_name("transport")] = "grpc" }) -o = s:option(Flag, "grpc_health_check", translate("Health check")) -add_xray_depends(o, { transport = "grpc" }) +o = s:option(Flag, option_name("grpc_health_check"), translate("Health check")) +add_xray_depends(o, { [option_name("transport")] = "grpc" }) -o = s:option(Value, "grpc_idle_timeout", translate("Idle timeout")) +o = s:option(Value, option_name("grpc_idle_timeout"), translate("Idle timeout")) o.default = "10" -add_xray_depends(o, { grpc_health_check = true }) +add_xray_depends(o, { [option_name("grpc_health_check")] = true }) -o = s:option(Value, "grpc_health_check_timeout", translate("Health check timeout")) +o = s:option(Value, option_name("grpc_health_check_timeout"), translate("Health check timeout")) o.default = "20" -add_xray_depends(o, { grpc_health_check = true }) +add_xray_depends(o, { [option_name("grpc_health_check")] = true }) -o = s:option(Flag, "grpc_permit_without_stream", translate("Permit without stream")) +o = s:option(Flag, option_name("grpc_permit_without_stream"), translate("Permit without stream")) o.default = "0" -add_xray_depends(o, { grpc_health_check = true }) +add_xray_depends(o, { [option_name("grpc_health_check")] = true }) -o = s:option(Value, "grpc_initial_windows_size", translate("Initial Windows Size")) +o = s:option(Value, option_name("grpc_initial_windows_size"), translate("Initial Windows Size")) o.default = "0" -add_xray_depends(o, { transport = "grpc" }) +add_xray_depends(o, { [option_name("transport")] = "grpc" }) -- [[ Mux ]]-- -o = s:option(Flag, "mux", translate("Mux")) -add_v2ray_depends(o, { xray_protocol = "vmess" }) -add_v2ray_depends(o, { xray_protocol = "vless" }) -add_v2ray_depends(o, { xray_protocol = "http" }) -add_v2ray_depends(o, { xray_protocol = "socks" }) -add_v2ray_depends(o, { xray_protocol = "shadowsocks" }) -add_v2ray_depends(o, { xray_protocol = "trojan" }) -add_xray_depends(o, { xray_protocol = "vmess" }) -add_xray_depends(o, { xray_protocol = "vless", xray_tlsflow = "" }) -add_xray_depends(o, { xray_protocol = "http" }) -add_xray_depends(o, { xray_protocol = "socks" }) -add_xray_depends(o, { xray_protocol = "shadowsocks" }) -add_xray_depends(o, { xray_protocol = "trojan" }) +o = s:option(Flag, option_name("mux"), translate("Mux")) +add_v2ray_depends(o, { [option_name("protocol")] = "vmess" }) +add_v2ray_depends(o, { [option_name("protocol")] = "vless" }) +add_v2ray_depends(o, { [option_name("protocol")] = "http" }) +add_v2ray_depends(o, { [option_name("protocol")] = "socks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" }) +add_v2ray_depends(o, { [option_name("protocol")] = "trojan" }) +add_xray_depends(o, { [option_name("protocol")] = "vmess" }) +add_xray_depends(o, { [option_name("protocol")] = "vless", [option_name("tlsflow")] = "" }) +add_xray_depends(o, { [option_name("protocol")] = "http" }) +add_xray_depends(o, { [option_name("protocol")] = "socks" }) +add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" }) +add_xray_depends(o, { [option_name("protocol")] = "trojan" }) -o = s:option(Value, "mux_concurrency", translate("Mux concurrency")) +o = s:option(Value, option_name("mux_concurrency"), translate("Mux concurrency")) o.default = 8 -add_xray_depends(o, { mux = true }) -add_v2ray_depends(o, { mux = true }) +add_xray_depends(o, { [option_name("mux")] = true }) +add_v2ray_depends(o, { [option_name("mux")] = true }) -- [[ XUDP Mux ]]-- -o = s:option(Flag, "xmux", translate("xMux")) +o = s:option(Flag, option_name("xmux"), translate("xMux")) o.default = 1 -add_xray_depends(o, { xray_protocol = "vless", xray_tlsflow = "xtls-rprx-vision" }) -add_xray_depends(o, { xray_protocol = "vless", xray_tlsflow = "xtls-rprx-vision-udp443" }) +add_xray_depends(o, { [option_name("protocol")] = "vless", [option_name("tlsflow")] = "xtls-rprx-vision" }) +add_xray_depends(o, { [option_name("protocol")] = "vless", [option_name("tlsflow")] = "xtls-rprx-vision-udp443" }) -o = s:option(Value, "xudp_concurrency", translate("XUDP Mux concurrency")) +o = s:option(Value, option_name("xudp_concurrency"), translate("XUDP Mux concurrency")) o.default = 8 -add_xray_depends(o, { xmux = true }) +add_xray_depends(o, { [option_name("xmux")] = true }) -s.fields["xray_protocol"].validate = function(self, value) - if value == "_shunt" or value == "_balancing" then - s.fields["xray_address"].rmempty = true - s.fields["xray_port"].rmempty = true +for key, value in pairs(s.fields) do + if key:find(option_prefix) == 1 then + if not s.fields[key].not_rewrite then + s.fields[key].cfgvalue = rm_prefix_cfgvalue + s.fields[key].write = rm_prefix_write + s.fields[key].remove = rm_prefix_remove + end end - return value end diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ss-rust.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ss-rust.lua index fc40f7b6a..40ba9f70f 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ss-rust.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ss-rust.lua @@ -6,6 +6,8 @@ if not api.is_finded("sslocal") then return end +local type_name = "SS-Rust" + local option_prefix = "ssrust_" local function option_name(name) @@ -18,8 +20,17 @@ local function rm_prefix_cfgvalue(self, section) end end local function rm_prefix_write(self, section, value) - if self.option:find(option_prefix) == 1 then - m:set(section, self.option:sub(1 + #option_prefix), value) + if s.fields["type"]:formvalue(arg[1]) == type_name then + if self.option:find(option_prefix) == 1 then + m:set(section, self.option:sub(1 + #option_prefix), value) + end + end +end +local function rm_prefix_remove(self, section, value) + if s.fields["type"]:formvalue(arg[1]) == type_name then + if self.option:find(option_prefix) == 1 then + m:del(section, self.option:sub(1 + #option_prefix)) + end end end @@ -31,52 +42,53 @@ local ssrust_encrypt_method_list = { -- [[ Shadowsocks Rust ]] -s.fields["type"]:value("SS-Rust", translate("Shadowsocks Rust")) +s.fields["type"]:value(type_name, translate("Shadowsocks Rust")) -o = s:option(Value, "ssrust_address", translate("Address (Support Domain Name)")) +o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) -o = s:option(Value, "ssrust_port", translate("Port")) +o = s:option(Value, option_name("port"), translate("Port")) o.datatype = "port" -o = s:option(Value, "ssrust_password", translate("Password")) +o = s:option(Value, option_name("password"), translate("Password")) o.password = true -o = s:option(Value, "ssrust_method", translate("Encrypt Method")) +o = s:option(Value, option_name("method"), translate("Encrypt Method")) for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end -o = s:option(Value, "ssrust_timeout", translate("Connection Timeout")) +o = s:option(Value, option_name("timeout"), translate("Connection Timeout")) o.datatype = "uinteger" o.default = 300 -o = s:option(ListValue, "ssrust_tcp_fast_open", "TCP " .. translate("Fast Open"), translate("Need node support required")) +o = s:option(ListValue, option_name("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required")) o:value("false") o:value("true") -o = s:option(ListValue, "ssrust_plugin", translate("plugin")) +o = s:option(ListValue, option_name("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, "ssrust_plugin_opts", translate("opts")) -o:depends({ ssrust_plugin = "xray-plugin"}) -o:depends({ ssrust_plugin = "v2ray-plugin"}) -o:depends({ ssrust_plugin = "obfs-local"}) +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"}) for key, value in pairs(s.fields) do if key:find(option_prefix) == 1 then if not s.fields[key].not_rewrite then s.fields[key].cfgvalue = rm_prefix_cfgvalue s.fields[key].write = rm_prefix_write + s.fields[key].remove = rm_prefix_remove end local deps = s.fields[key].deps if #deps > 0 then for index, value in ipairs(deps) do - deps[index]["type"] = "SS-Rust" + deps[index]["type"] = type_name end else - s.fields[key]:depends({ type = "SS-Rust" }) + s.fields[key]:depends({ type = type_name }) end end end diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ss.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ss.lua index 8dbead41b..6df5d2af7 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ss.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ss.lua @@ -6,6 +6,8 @@ if not api.is_finded("ss-redir") then return end +local type_name = "SS" + local option_prefix = "ss_" local function option_name(name) @@ -18,8 +20,17 @@ local function rm_prefix_cfgvalue(self, section) end end local function rm_prefix_write(self, section, value) - if self.option:find(option_prefix) == 1 then - m:set(section, self.option:sub(1 + #option_prefix), value) + if s.fields["type"]:formvalue(arg[1]) == type_name then + if self.option:find(option_prefix) == 1 then + m:set(section, self.option:sub(1 + #option_prefix), value) + end + end +end +local function rm_prefix_remove(self, section, value) + if s.fields["type"]:formvalue(arg[1]) == type_name then + if self.option:find(option_prefix) == 1 then + m:del(section, self.option:sub(1 + #option_prefix)) + end end end @@ -32,52 +43,53 @@ local ss_encrypt_method_list = { -- [[ Shadowsocks Libev ]] -s.fields["type"]:value("SS", translate("Shadowsocks Libev")) +s.fields["type"]:value(type_name, translate("Shadowsocks Libev")) -o = s:option(Value, "ss_address", translate("Address (Support Domain Name)")) +o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) -o = s:option(Value, "ss_port", translate("Port")) +o = s:option(Value, option_name("port"), translate("Port")) o.datatype = "port" -o = s:option(Value, "ss_password", translate("Password")) +o = s:option(Value, option_name("password"), translate("Password")) o.password = true -o = s:option(Value, "ss_method", translate("Encrypt Method")) +o = s:option(Value, option_name("method"), translate("Encrypt Method")) for a, t in ipairs(ss_encrypt_method_list) do o:value(t) end -o = s:option(Value, "ss_timeout", translate("Connection Timeout")) +o = s:option(Value, option_name("timeout"), translate("Connection Timeout")) o.datatype = "uinteger" o.default = 300 -o = s:option(ListValue, "ss_tcp_fast_open", "TCP " .. translate("Fast Open"), translate("Need node support required")) +o = s:option(ListValue, option_name("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required")) o:value("false") o:value("true") -o = s:option(ListValue, "ss_plugin", translate("plugin")) +o = s:option(ListValue, option_name("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, "ss_plugin_opts", translate("opts")) -o:depends({ ss_plugin = "xray-plugin"}) -o:depends({ ss_plugin = "v2ray-plugin"}) -o:depends({ ss_plugin = "obfs-local"}) +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"}) for key, value in pairs(s.fields) do if key:find(option_prefix) == 1 then if not s.fields[key].not_rewrite then s.fields[key].cfgvalue = rm_prefix_cfgvalue s.fields[key].write = rm_prefix_write + s.fields[key].remove = rm_prefix_remove end local deps = s.fields[key].deps if #deps > 0 then for index, value in ipairs(deps) do - deps[index]["type"] = "SS" + deps[index]["type"] = type_name end else - s.fields[key]:depends({ type = "SS" }) + s.fields[key]:depends({ type = type_name }) end end end diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ssr.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ssr.lua index 0a675255e..b8ae094ed 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ssr.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ssr.lua @@ -6,6 +6,8 @@ if not api.is_finded("ssr-redir") then return end +local type_name = "SSR" + local option_prefix = "ssr_" local function option_name(name) @@ -18,8 +20,17 @@ local function rm_prefix_cfgvalue(self, section) end end local function rm_prefix_write(self, section, value) - if self.option:find(option_prefix) == 1 then - m:set(section, self.option:sub(1 + #option_prefix), value) + if s.fields["type"]:formvalue(arg[1]) == type_name then + if self.option:find(option_prefix) == 1 then + m:set(section, self.option:sub(1 + #option_prefix), value) + end + end +end +local function rm_prefix_remove(self, section, value) + if s.fields["type"]:formvalue(arg[1]) == type_name then + if self.option:find(option_prefix) == 1 then + m:del(section, self.option:sub(1 + #option_prefix)) + end end end @@ -44,34 +55,34 @@ local ssr_obfs_list = { -- [[ ShadowsocksR Libev ]] -s.fields["type"]:value("SSR", translate("ShadowsocksR Libev")) +s.fields["type"]:value(type_name, translate("ShadowsocksR Libev")) -o = s:option(Value, "ssr_address", translate("Address (Support Domain Name)")) +o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) -o = s:option(Value, "ssr_port", translate("Port")) +o = s:option(Value, option_name("port"), translate("Port")) o.datatype = "port" -o = s:option(Value, "ssr_password", translate("Password")) +o = s:option(Value, option_name("password"), translate("Password")) o.password = true -o = s:option(ListValue, "ssr_method", translate("Encrypt Method")) +o = s:option(ListValue, option_name("method"), translate("Encrypt Method")) for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end -o = s:option(ListValue, "ssr_protocol", translate("Protocol")) +o = s:option(ListValue, option_name("protocol"), translate("Protocol")) for a, t in ipairs(ssr_protocol_list) do o:value(t) end -o = s:option(Value, "ssr_protocol_param", translate("Protocol_param")) +o = s:option(Value, option_name("protocol_param"), translate("Protocol_param")) -o = s:option(ListValue, "ssr_obfs", translate("Obfs")) +o = s:option(ListValue, option_name("obfs"), translate("Obfs")) for a, t in ipairs(ssr_obfs_list) do o:value(t) end -o = s:option(Value, "ssr_obfs_param", translate("Obfs_param")) +o = s:option(Value, option_name("obfs_param"), translate("Obfs_param")) -o = s:option(Value, "ssr_timeout", translate("Connection Timeout")) +o = s:option(Value, option_name("timeout"), translate("Connection Timeout")) o.datatype = "uinteger" o.default = 300 -o = s:option(ListValue, "ssr_tcp_fast_open", "TCP " .. translate("Fast Open"), translate("Need node support required")) +o = s:option(ListValue, option_name("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required")) o:value("false") o:value("true") @@ -80,15 +91,16 @@ for key, value in pairs(s.fields) do if not s.fields[key].not_rewrite then s.fields[key].cfgvalue = rm_prefix_cfgvalue s.fields[key].write = rm_prefix_write + s.fields[key].remove = rm_prefix_remove end local deps = s.fields[key].deps if #deps > 0 then for index, value in ipairs(deps) do - deps[index]["type"] = "SSR" + deps[index]["type"] = type_name end else - s.fields[key]:depends({ type = "SSR" }) + s.fields[key]:depends({ type = type_name }) end end end diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/tuic.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/tuic.lua index 8dcd30c48..000c015c2 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/tuic.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/tuic.lua @@ -6,6 +6,8 @@ if not api.is_finded("tuic-client") then return end +local type_name = "TUIC" + local option_prefix = "tuic_" local function option_name(name) @@ -18,25 +20,34 @@ local function rm_prefix_cfgvalue(self, section) end end local function rm_prefix_write(self, section, value) - if self.option:find(option_prefix) == 1 then - m:set(section, self.option:sub(1 + #option_prefix), value) + if s.fields["type"]:formvalue(arg[1]) == type_name then + if self.option:find(option_prefix) == 1 then + m:set(section, self.option:sub(1 + #option_prefix), value) + end + end +end +local function rm_prefix_remove(self, section, value) + if s.fields["type"]:formvalue(arg[1]) == type_name then + if self.option:find(option_prefix) == 1 then + m:del(section, self.option:sub(1 + #option_prefix)) + end end end -- [[ TUIC ]] -s.fields["type"]:value("TUIC", translate("TUIC")) +s.fields["type"]:value(type_name, translate("TUIC")) -o = s:option(Value, "tuic_address", translate("Address (Support Domain Name)")) +o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)")) -o = s:option(Value, "tuic_port", translate("Port")) +o = s:option(Value, option_name("port"), translate("Port")) o.datatype = "port" -o = s:option(Value, "tuic_uuid", translate("ID")) +o = s:option(Value, option_name("uuid"), translate("ID")) o.password = true -- Tuic Password for remote server connect -o = s:option(Value, "tuic_password", translate("TUIC User Password For Connect Remote Server")) +o = s:option(Value, option_name("password"), translate("TUIC User Password For Connect Remote Server")) o.password = true o.rmempty = true o.default = "" @@ -44,32 +55,32 @@ o.not_rewrite = true --[[ -- Tuic username for local socks connect -o = s:option(Value, "tuic_socks_username", translate("TUIC UserName For Local Socks")) +o = s:option(Value, option_name("socks_username"), translate("TUIC UserName For Local Socks")) o.rmempty = true o.default = "" o.not_rewrite = true -- Tuic Password for local socks connect -o = s:option(Value, "tuic_socks_password", translate("TUIC Password For Local Socks")) +o = s:option(Value, option_name("socks_password"), translate("TUIC Password For Local Socks")) o.password = true o.rmempty = true o.default = "" o.not_rewrite = true --]] -o = s:option(Value, "tuic_ip", translate("Set the TUIC proxy server ip address")) +o = s:option(Value, option_name("ip"), translate("Set the TUIC proxy server ip address")) o.datatype = "ipaddr" o.rmempty = true o.not_rewrite = true -o = s:option(ListValue, "tuic_udp_relay_mode", translate("UDP relay mode")) +o = s:option(ListValue, option_name("udp_relay_mode"), translate("UDP relay mode")) o:value("native", translate("native")) o:value("quic", translate("QUIC")) o.default = "native" o.rmempty = true o.not_rewrite = true -o = s:option(ListValue, "tuic_congestion_control", translate("Congestion control algorithm")) +o = s:option(ListValue, option_name("congestion_control"), translate("Congestion control algorithm")) o:value("bbr", translate("BBR")) o:value("cubic", translate("CUBIC")) o:value("new_reno", translate("New Reno")) @@ -77,65 +88,65 @@ o.default = "cubic" o.rmempty = true o.not_rewrite = true -o = s:option(Value, "tuic_heartbeat", translate("Heartbeat interval(second)")) +o = s:option(Value, option_name("heartbeat"), translate("Heartbeat interval(second)")) o.datatype = "uinteger" o.default = "3" o.rmempty = true o.not_rewrite = true -o = s:option(Value, "tuic_timeout", translate("Timeout for establishing a connection to server(second)")) +o = s:option(Value, option_name("timeout"), translate("Timeout for establishing a connection to server(second)")) o.datatype = "uinteger" o.default = "8" o.rmempty = true o.not_rewrite = true -o = s:option(Value, "tuic_gc_interval", translate("Garbage collection interval(second)")) +o = s:option(Value, option_name("gc_interval"), translate("Garbage collection interval(second)")) o.datatype = "uinteger" o.default = "3" o.rmempty = true o.not_rewrite = true -o = s:option(Value, "tuic_gc_lifetime", translate("Garbage collection lifetime(second)")) +o = s:option(Value, option_name("gc_lifetime"), translate("Garbage collection lifetime(second)")) o.datatype = "uinteger" o.default = "15" o.rmempty = true o.not_rewrite = true -o = s:option(Value, "tuic_send_window", translate("TUIC send window")) +o = s:option(Value, option_name("send_window"), translate("TUIC send window")) o.datatype = "uinteger" o.default = 20971520 o.rmempty = true o.not_rewrite = true -o = s:option(Value, "tuic_receive_window", translate("TUIC receive window")) +o = s:option(Value, option_name("receive_window"), translate("TUIC receive window")) o.datatype = "uinteger" o.default = 10485760 o.rmempty = true o.not_rewrite = true -o = s:option(Value, "tuic_max_package_size", translate("TUIC Maximum packet size the socks5 server can receive from external, in bytes")) +o = s:option(Value, option_name("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.not_rewrite = true --Tuic settings for the local inbound socks5 server -o = s:option(Flag, "tuic_dual_stack", translate("Set if the listening socket should be dual-stack")) +o = s:option(Flag, option_name("dual_stack"), translate("Set if the listening socket should be dual-stack")) o.default = 0 o.rmempty = true o.not_rewrite = true -o = s:option(Flag, "tuic_disable_sni", translate("Disable SNI")) +o = s:option(Flag, option_name("disable_sni"), translate("Disable SNI")) o.default = 0 o.rmempty = true o.not_rewrite = true -o = s:option(Flag, "tuic_zero_rtt_handshake", translate("Enable 0-RTT QUIC handshake")) +o = s:option(Flag, option_name("zero_rtt_handshake"), translate("Enable 0-RTT QUIC handshake")) o.default = 0 o.rmempty = true o.not_rewrite = true -o = s:option(DynamicList, "tuic_tls_alpn", translate("TLS ALPN")) +o = s:option(DynamicList, option_name("tls_alpn"), translate("TLS ALPN")) o.rmempty = true o.not_rewrite = true @@ -144,15 +155,16 @@ for key, value in pairs(s.fields) do if not s.fields[key].not_rewrite then s.fields[key].cfgvalue = rm_prefix_cfgvalue s.fields[key].write = rm_prefix_write + s.fields[key].remove = rm_prefix_remove end local deps = s.fields[key].deps if #deps > 0 then for index, value in ipairs(deps) do - deps[index]["type"] = "TUIC" + deps[index]["type"] = type_name end else - s.fields[key]:depends({ type = "TUIC" }) + s.fields[key]:depends({ type = type_name }) end end end diff --git a/luci-app-passwall2/root/usr/share/passwall2/app.sh b/luci-app-passwall2/root/usr/share/passwall2/app.sh index 40da48a4a..70515aec9 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/app.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/app.sh @@ -1065,9 +1065,6 @@ add_ip2route) get_new_port) get_new_port $@ ;; -run_v2ray) - run_v2ray $@ - ;; run_socks) run_socks $@ ;; diff --git a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua index 64e16ffda..646645ade 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua +++ b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua @@ -121,6 +121,9 @@ do set = function(o, server) uci:set(appname, t[".name"], option, server) o.newNodeId = server + end, + delete = function(o) + uci:delete(appname, t[".name"]) end } end) @@ -140,6 +143,9 @@ do set = function(o, server) uci:set(appname, t[".name"], option, server) o.newNodeId = server + end, + delete = function(o) + uci:delete(appname, t[".name"]) end } end) @@ -228,15 +234,20 @@ do for k, e in pairs(rules) do local _node_id = node[e[".name"]] or nil - CONFIG[#CONFIG + 1] = { - log = false, - currentNode = _node_id and uci:get_all(appname, _node_id) or nil, - remarks = "分流" .. e.remarks .. "节点", - set = function(o, server) - uci:set(appname, node_id, e[".name"], server) - o.newNodeId = server - end - } + if _node_id and (_node_id:find("socks://") == 1 or _node_id:find("http://") == 1) then + else + CONFIG[#CONFIG + 1] = { + log = false, + 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 + uci:set(appname, node_id, e[".name"], server) + o.newNodeId = server + end + } + end + end elseif node.protocol and node.protocol == '_balancing' then local node_id = node[".name"] @@ -288,7 +299,8 @@ do end end else - if v.currentNode == nil then + if v.currentNode == nil and v.delete then + v.delete() CONFIG[k] = nil end end @@ -810,23 +822,13 @@ local function truncate_nodes(add_from) end local function select_node(nodes, config) - local server if config.currentNode then - -- 特别优先级 分流 + 备注 - if config.currentNode.protocol and config.currentNode.protocol == '_shunt' then + local server + -- 特别优先级 cfgid + if config.currentNode[".name"] then for index, node in pairs(nodes) do - if node.remarks == config.currentNode.remarks then - log('更新【' .. config.remarks .. '】分流匹配节点:' .. node.remarks) - server = node[".name"] - break - end - end - end - -- 特别优先级 负载均衡 + 备注 - if config.currentNode.protocol and config.currentNode.protocol == '_balancing' then - for index, node in pairs(nodes) do - if node.remarks == config.currentNode.remarks then - log('更新【' .. config.remarks .. '】负载均衡匹配节点:' .. node.remarks) + if node[".name"] == config.currentNode[".name"] then + log('更新【' .. config.remarks .. '】匹配节点:' .. node.remarks) server = node[".name"] break end @@ -912,24 +914,26 @@ local function select_node(nodes, config) end end end - end - -- 还不行 随便找一个 - if not server then - local nodes_table = {} - for k, e in ipairs(api.get_valid_nodes()) do - if e.node_type == "normal" then - nodes_table[#nodes_table + 1] = e + -- 还不行 随便找一个 + if not server then + local nodes_table = {} + for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" then + nodes_table[#nodes_table + 1] = e + end + end + if #nodes_table > 0 then + if config.log == nil or config.log == true then + log('【' .. config.remarks .. '】' .. '无法找到最匹配的节点,当前已更换为:' .. nodes_table[1].remarks) + end + server = nodes_table[1][".name"] end end - if #nodes_table > 0 then - if config.log == nil or config.log == true then - log('【' .. config.remarks .. '】' .. '无法找到最匹配的节点,当前已更换为:' .. nodes_table[1].remarks) - end - server = nodes_table[1][".name"] + if server then + config.set(config, server) end - end - if server then - config.set(config, server) + else + config.set(config, nil) end end diff --git a/natflow/Makefile b/natflow/Makefile index 1b764b454..972106a87 100644 --- a/natflow/Makefile +++ b/natflow/Makefile @@ -9,10 +9,10 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=natflow -PKG_VERSION:=20230831 +PKG_VERSION:=20230902 PKG_SOURCE_URL:=https://codeload.github.com/ptpt52/natflow/tar.gz/$(PKG_VERSION)? -PKG_HASH:=2c153afda635fc8f5ab57192395d015d3aefd7d14d33cba268d06bbab44c21b7 +PKG_HASH:=05beb1978963c38f4f7d1df91066b19523661001794e4e516fe8e5e2089eff68 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_MAINTAINER:=Chen Minqiang