From 81adc908e8e0f9e8d4f06c15d4d6334e01a87f99 Mon Sep 17 00:00:00 2001
From: xiaorouji <60100640+xiaorouji@users.noreply.github.com>
Date: Sat, 2 Sep 2023 01:31:23 +0800
Subject: [PATCH] luci: optimization
---
.../model/cbi/passwall/client/other.lua | 19 +-
.../model/cbi/passwall/client/type/brook.lua | 38 +-
.../cbi/passwall/client/type/hysteria.lua | 67 +-
.../model/cbi/passwall/client/type/naive.lua | 32 +-
.../model/cbi/passwall/client/type/ray.lua | 658 +++++++++---------
.../cbi/passwall/client/type/ss-rust.lua | 44 +-
.../model/cbi/passwall/client/type/ss.lua | 46 +-
.../model/cbi/passwall/client/type/ssr.lua | 44 +-
.../cbi/passwall/client/type/trojan-go.lua | 104 +--
.../cbi/passwall/client/type/trojan-plus.lua | 46 +-
.../model/cbi/passwall/client/type/tuic.lua | 62 +-
.../model/cbi/passwall/server/type/brook.lua | 41 +-
.../cbi/passwall/server/type/hysteria.lua | 65 +-
.../model/cbi/passwall/server/type/ray.lua | 482 +++++++------
.../model/cbi/passwall/server/type/socks.lua | 42 +-
.../cbi/passwall/server/type/ss-rust.lua | 35 +-
.../model/cbi/passwall/server/type/ss.lua | 35 +-
.../model/cbi/passwall/server/type/ssr.lua | 45 +-
.../cbi/passwall/server/type/trojan-go.lua | 106 +--
.../cbi/passwall/server/type/trojan-plus.lua | 64 +-
luci-app-passwall/luasrc/passwall/api.lua | 6 +-
luci-app-passwall/po/zh-cn/passwall.po | 23 +-
.../root/etc/uci-defaults/luci-passwall | 17 +-
.../root/usr/share/passwall/0_default_config | 2 +
24 files changed, 1164 insertions(+), 959 deletions(-)
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua
index 2a4b195c2..3b646a5d2 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua
@@ -141,30 +141,33 @@ o:depends("ipv6_tproxy", true)
o.default = 0
if has_v2ray or has_xray then
- o = s:option(Flag, "sniffing", translate("Sniffing (V2Ray/Xray)"), translate("When using the V2ray/Xray shunt, must be enabled, otherwise the shunt will invalid."))
+ s = m:section(TypedSection, "global_xray", "V2Ray/Xray " .. translate("Settings"))
+ s.anonymous = true
+ s.addremove = false
+
+ o = s:option(Flag, "sniffing", translate("Sniffing"), translate("When using the shunt, must be enabled, otherwise the shunt will invalid."))
o.default = 1
o.rmempty = false
if has_xray then
- route_only = s:option(Flag, "route_only", translate("Sniffing Route Only (Xray)"), translate("When enabled, the server not will resolve the domain name again."))
- route_only.default = 0
- route_only:depends("sniffing", true)
+ o = s:option(Flag, "route_only", translate("Sniffing Route Only"))
+ o.default = 0
+ o:depends("sniffing", true)
local domains_excluded = string.format("/usr/share/%s/rules/domains_excluded", appname)
- o = s:option(TextValue, "no_sniffing_hosts", translate("No Sniffing Lists"), translate("Hosts added into No Sniffing Lists will not resolve again on server (Xray only)."))
+ o = s:option(TextValue, "no_sniffing_hosts", translate("No Sniffing Lists"), translate("Hosts added into No Sniffing Lists will not resolve again on server."))
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return fs.readfile(domains_excluded) or "" end
o.write = function(self, section, value) fs.writefile(domains_excluded, value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value)
- if route_only:formvalue(section) == "0" then
+ if s.fields["route_only"]:formvalue(section) == "0" then
fs.writefile(domains_excluded, "")
end
end
o:depends({sniffing = true, route_only = false})
- o = s:option(Value, "buffer_size", translate("Buffer Size (Xray)"), translate("Buffer size for every connection (kB)"))
- o.rmempty = true
+ o = s:option(Value, "buffer_size", translate("Buffer Size"), translate("Buffer size for every connection (kB)"))
o.datatype = "uinteger"
end
end
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/brook.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/brook.lua
index f6ece22f1..41fc2f096 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/brook.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/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-passwall/luasrc/model/cbi/passwall/client/type/hysteria.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/hysteria.lua
index 3039accda..87f5afa87 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/hysteria.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/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-passwall/luasrc/model/cbi/passwall/client/type/naive.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/naive.lua
index 6bc5a4a4a..9c9a5a9b0 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/naive.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/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-passwall/luasrc/model/cbi/passwall/client/type/ray.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua
index ae257566f..2f15d6108 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/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 = "
- " .. translate("'AsIs': Only use domain for routi
.. "
- " .. translate("'IPIfNonMatch': When no rule matches current domain, resolves it into IP addresses (A or AAAA records) and try all rules again.")
.. "
- " .. translate("'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately.")
.. "
"
-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-passwall/luasrc/model/cbi/passwall/client/type/ss-rust.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ss-rust.lua
index 00e657dd9..c6bf3ee9d 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ss-rust.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/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-passwall/luasrc/model/cbi/passwall/client/type/ss.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ss.lua
index 3fff67294..f9646d018 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ss.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ss.lua
@@ -2,10 +2,12 @@ local m, s = ...
local api = require "luci.passwall.api"
-if not api.is_finded("ss-redir") then
+if not api.is_finded("ss-local") and 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-passwall/luasrc/model/cbi/passwall/client/type/ssr.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ssr.lua
index 7df040330..45257dd78 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ssr.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ssr.lua
@@ -2,10 +2,12 @@ local m, s = ...
local api = require "luci.passwall.api"
-if not api.is_finded("ssr-redir") then
+if not api.is_finded("ssr-local") and 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-passwall/luasrc/model/cbi/passwall/client/type/trojan-go.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/trojan-go.lua
index 04cdbfe45..215ac1379 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/trojan-go.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/trojan-go.lua
@@ -6,6 +6,8 @@ if not api.is_finded("trojan-go") then
return
end
+local type_name = "Trojan-Go"
+
local option_prefix = "trojan_go_"
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,43 +42,43 @@ local encrypt_methods_ss_aead = {
-- [[ Trojan Go ]]
-s.fields["type"]:value("Trojan-Go", translate("Trojan-Go"))
+s.fields["type"]:value(type_name, "Trojan-Go")
-o = s:option(Value, "trojan_go_address", translate("Address (Support Domain Name)"))
+o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)"))
-o = s:option(Value, "trojan_go_port", translate("Port"))
+o = s:option(Value, option_name("port"), translate("Port"))
o.datatype = "port"
-o = s:option(Value, "trojan_go_password", translate("Password"))
+o = s:option(Value, option_name("password"), translate("Password"))
o.password = true
-o = s:option(ListValue, "trojan_go_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(Flag, "trojan_go_tls", translate("TLS"))
+o = s:option(Flag, option_name("tls"), translate("TLS"))
o.default = 1
-o = s:option(Flag, "trojan_go_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:depends({ trojan_go_tls = true })
+o:depends({ [option_name("tls")] = true })
-o = s:option(Value, "trojan_go_tls_serverName", translate("Domain"))
-o:depends({ trojan_go_tls = true })
+o = s:option(Value, option_name("tls_serverName"), translate("Domain"))
+o:depends({ [option_name("tls")] = true })
-o = s:option(Flag, "trojan_go_tls_sessionTicket", translate("Session Ticket"))
+o = s:option(Flag, option_name("tls_sessionTicket"), translate("Session Ticket"))
o.default = "0"
-o:depends({ trojan_go_tls = true })
+o:depends({ [option_name("tls")] = true })
-o = s:option(ListValue, "trojan_go_fingerprint", translate("Finger Print"))
+o = s:option(ListValue, option_name("fingerprint"), translate("Finger Print"))
o:value("disable", translate("Disable"))
o:value("firefox")
o:value("chrome")
o:value("ios")
o.default = "disable"
-o:depends({ trojan_go_tls = true })
+o:depends({ [option_name("tls")] = true })
-o = s:option(ListValue, "trojan_go_transport", translate("Transport"))
+o = s:option(ListValue, option_name("transport"), translate("Transport"))
o:value("original", translate("Original"))
o:value("ws", "WebSocket")
o.default = "original"
@@ -76,75 +87,78 @@ function o.cfgvalue(self, section)
return m:get(section, "trojan_transport")
end
function o.write(self, section, value)
- m:set(section, "trojan_transport", value)
+ if s.fields["type"]:formvalue(arg[1]) == type_name then
+ m:set(section, "trojan_transport", value)
+ end
end
-o = s:option(ListValue, "trojan_go_plugin_type", translate("Transport Plugin"))
+o = s:option(ListValue, option_name("plugin_type"), translate("Transport Plugin"))
o:value("plaintext", "Plain Text")
o:value("shadowsocks", "ShadowSocks")
o:value("other", "Other")
o.default = "plaintext"
-o:depends({ trojan_go_tls = false, trojan_go_transport = "original" })
+o:depends({ [option_name("tls")] = false, [option_name("transport")] = "original" })
-o = s:option(Value, "trojan_go_plugin_cmd", translate("Plugin Binary"))
+o = s:option(Value, option_name("plugin_cmd"), translate("Plugin Binary"))
o.placeholder = "eg: /usr/bin/v2ray-plugin"
-o:depends({ trojan_go_plugin_type = "shadowsocks" })
-o:depends({ trojan_go_plugin_type = "other" })
+o:depends({ [option_name("plugin_type")] = "shadowsocks" })
+o:depends({ [option_name("plugin_type")] = "other" })
-o = s:option(Value, "trojan_go_plugin_option", translate("Plugin Option"))
+o = s:option(Value, option_name("plugin_option"), translate("Plugin Option"))
o.placeholder = "eg: obfs=http;obfs-host=www.baidu.com"
-o:depends({ trojan_go_plugin_type = "shadowsocks" })
-o:depends({ trojan_go_plugin_type = "other" })
+o:depends({ [option_name("plugin_type")] = "shadowsocks" })
+o:depends({ [option_name("plugin_type")] = "other" })
-o = s:option(DynamicList, "trojan_go_plugin_arg", translate("Plugin Option Args"))
+o = s:option(DynamicList, option_name("plugin_arg"), translate("Plugin Option Args"))
o.placeholder = "eg: [\"-config\", \"test.json\"]"
-o:depends({ trojan_go_plugin_type = "shadowsocks" })
-o:depends({ trojan_go_plugin_type = "other" })
+o:depends({ [option_name("plugin_type")] = "shadowsocks" })
+o:depends({ [option_name("plugin_type")] = "other" })
-o = s:option(Value, "trojan_go_ws_host", translate("WebSocket Host"))
-o:depends({ trojan_go_transport = "ws" })
+o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
+o:depends({ [option_name("transport")] = "ws" })
-o = s:option(Value, "trojan_go_ws_path", translate("WebSocket Path"))
+o = s:option(Value, option_name("ws_path"), translate("WebSocket Path"))
o.placeholder = "/"
-o:depends({ trojan_go_transport = "ws" })
+o:depends({ [option_name("transport")] = "ws" })
-- [[ Shadowsocks2 ]] --
-o = s:option(Flag, "trojan_go_ss_aead", translate("Shadowsocks secondary encryption"))
+o = s:option(Flag, option_name("ss_aead"), translate("Shadowsocks secondary encryption"))
o.default = "0"
-o = s:option(ListValue, "trojan_go_ss_aead_method", translate("Encrypt Method"))
+o = s:option(ListValue, option_name("ss_aead_method"), translate("Encrypt Method"))
for _, v in ipairs(encrypt_methods_ss_aead) do o:value(v, v) end
o.default = "aes-128-gcm"
-o:depends({ trojan_go_ss_aead = true })
+o:depends({ [option_name("ss_aead")] = true })
-o = s:option(Value, "trojan_go_ss_aead_pwd", translate("Password"))
+o = s:option(Value, option_name("ss_aead_pwd"), translate("Password"))
o.password = true
-o:depends({ trojan_go_ss_aead = true })
+o:depends({ [option_name("ss_aead")] = true })
-o = s:option(Flag, "trojan_go_smux", translate("Smux"))
+o = s:option(Flag, option_name("smux"), translate("Smux"))
-o = s:option(Value, "trojan_go_mux_concurrency", translate("Mux concurrency"))
+o = s:option(Value, option_name("mux_concurrency"), translate("Mux concurrency"))
o.default = 8
-o:depends({ trojan_go_smux = true })
+o:depends({ [option_name("smux")] = true })
-o = s:option(Value, "trojan_go_smux_idle_timeout", translate("Mux idle timeout"))
+o = s:option(Value, option_name("smux_idle_timeout"), translate("Mux idle timeout"))
o.default = 60
-o:depends({ trojan_go_smux = true })
+o:depends({ [option_name("smux")] = 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
local deps = s.fields[key].deps
if #deps > 0 then
for index, value in ipairs(deps) do
- deps[index]["type"] = "Trojan-Go"
+ deps[index]["type"] = type_name
end
else
- s.fields[key]:depends({ type = "Trojan-Go" })
+ s.fields[key]:depends({ type = type_name })
end
end
end
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/trojan-plus.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/trojan-plus.lua
index 7364b7c35..6dd12d59b 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/trojan-plus.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/trojan-plus.lua
@@ -6,6 +6,8 @@ if not api.is_finded("trojan-plus") then
return
end
+local type_name = "Trojan-Plus"
+
local option_prefix = "trojan_plus_"
local function option_name(name)
@@ -18,64 +20,74 @@ 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
-- [[ Trojan Plus ]]
-s.fields["type"]:value("Trojan-Plus", translate("Trojan-Plus"))
+s.fields["type"]:value(type_name, "Trojan-Plus")
-o = s:option(Value, "trojan_plus_address", translate("Address (Support Domain Name)"))
+o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)"))
-o = s:option(Value, "trojan_plus_port", translate("Port"))
+o = s:option(Value, option_name("port"), translate("Port"))
o.datatype = "port"
-o = s:option(Value, "trojan_plus_password", translate("Password"))
+o = s:option(Value, option_name("password"), translate("Password"))
o.password = true
-o = s:option(ListValue, "trojan_plus_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(Flag, "trojan_plus_tls", translate("TLS"))
+o = s:option(Flag, option_name("tls"), translate("TLS"))
o.default = 0
o.validate = function(self, value, t)
if value then
local type = s.fields["type"]:formvalue(t) or ""
- if value == "0" and type == "Trojan-Plus" then
+ if value == "0" and type == type_name then
return nil, translate("Original Trojan only supported 'tls', please choose 'tls'.")
end
return value
end
end
-o = s:option(Flag, "trojan_plus_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:depends({ trojan_plus_tls = true })
+o:depends({ [option_name("tls")] = true })
-o = s:option(Value, "trojan_plus_tls_serverName", translate("Domain"))
-o:depends({ trojan_plus_tls = true })
+o = s:option(Value, option_name("tls_serverName"), translate("Domain"))
+o:depends({ [option_name("tls")] = true })
-o = s:option(Flag, "trojan_plus_tls_sessionTicket", translate("Session Ticket"))
+o = s:option(Flag, option_name("tls_sessionTicket"), translate("Session Ticket"))
o.default = "0"
-o:depends({ trojan_plus_tls = true })
+o:depends({ [option_name("tls")] = 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
local deps = s.fields[key].deps
if #deps > 0 then
for index, value in ipairs(deps) do
- deps[index]["type"] = "Trojan-Plus"
+ deps[index]["type"] = type_name
end
else
- s.fields[key]:depends({ type = "Trojan-Plus" })
+ s.fields[key]:depends({ type = type_name })
end
end
end
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/tuic.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/tuic.lua
index 465a02eeb..270f7635a 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/tuic.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/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-passwall/luasrc/model/cbi/passwall/server/type/brook.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/brook.lua
index a18e6a13b..5e2e52ab8 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/brook.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/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,48 +20,59 @@ 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(Value, "brook_port", translate("Listen Port"))
+o = s:option(Value, option_name("port"), translate("Listen Port"))
o.datatype = "port"
-o = s:option(ListValue, "brook_protocol", translate("Protocol"))
+o = s:option(ListValue, option_name("protocol"), translate("Protocol"))
o:value("server", "Brook")
o:value("wsserver", "WebSocket")
---o = s:option(Flag, "brook_tls", translate("Use TLS"))
---o:depends({ brook_protocol = "wsserver" })
+--o = s:option(Flag, option_name("tls"), translate("Use TLS"))
+--o:depends({ [option_name("protocol")] = "wsserver" })
-o = s:option(Value, "brook_password", translate("Password"))
+o = s:option(Value, option_name("password"), translate("Password"))
o.password = true
-o = s:option(Value, "brook_ws_path", translate("WebSocket Path"))
-o:depends({ brook_protocol = "wsserver" })
+o = s:option(Value, option_name("ws_path"), translate("WebSocket Path"))
+o:depends({ [option_name("protocol")] = "wsserver" })
-o = s:option(Flag, "brook_log", translate("Log"))
+o = s:option(Flag, option_name("log"), translate("Log"))
o.default = "1"
+o.rmempty = false
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"] = "Brook"
+ deps[index]["type"] = type_name
end
else
- s.fields[key]:depends({ type = "Brook" })
+ s.fields[key]:depends({ type = type_name })
end
end
-end
\ No newline at end of file
+end
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/hysteria.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/hysteria.lua
index 248e06140..960e363df 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/hysteria.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/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,67 +20,76 @@ 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(Value, "hysteria_port", translate("Listen Port"))
+o = s:option(Value, option_name("port"), translate("Listen Port"))
o.datatype = "port"
-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_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.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({ [option_name("auth_type")] = "string" })
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_udp", translate("UDP"))
+o = s:option(Flag, option_name("udp"), translate("UDP"))
o.default = "1"
o.not_rewrite = true
-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(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_tls", translate("TLS"))
+o = s:option(Flag, option_name("tls"), translate("TLS"))
o.default = 0
o.validate = function(self, value, t)
if value then
if value == "1" then
- local ca = s.fields["hysteria_tls_certificateFile"]:formvalue(t) or ""
- local key = s.fields["hysteria_tls_keyFile"]:formvalue(t) or ""
+ local ca = s.fields[option_name("tls_certificateFile")]:formvalue(t) or ""
+ local key = s.fields[option_name("tls_keyFile")]:formvalue(t) or ""
if ca == "" or key == "" then
return nil, translate("Public key and Private key path can not be empty!")
end
@@ -87,9 +98,9 @@ o.validate = function(self, value, t)
end
end
-o = s:option(FileUpload, "hysteria_tls_certificateFile", translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
+o = s:option(FileUpload, option_name("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({ hysteria_tls = true })
+o:depends({ [option_name("tls")] = true })
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@@ -101,9 +112,9 @@ o.validate = function(self, value, t)
return nil
end
-o = s:option(FileUpload, "hysteria_tls_keyFile", translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
+o = s:option(FileUpload, option_name("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({ hysteria_tls = true })
+o:depends({ [option_name("tls")] = true })
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@@ -115,23 +126,25 @@ o.validate = function(self, value, t)
return nil
end
-o = s:option(Flag, "hysteria_log", translate("Log"))
+o = s:option(Flag, option_name("log"), translate("Log"))
o.default = "1"
+o.rmempty = false
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"] = "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-passwall/luasrc/model/cbi/passwall/server/type/ray.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ray.lua
index 48536f775..cfe1aa389 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ray.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ray.lua
@@ -18,8 +18,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 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
@@ -51,11 +60,11 @@ local function add_v2ray_depends(o, field, value)
o:depends(deps)
end
-local v_ss_encrypt_method_list = {
+local v_ss_method_list = {
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305"
}
-local x_ss_encrypt_method_list = {
+local x_ss_method_list = {
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "xchacha20-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
}
@@ -72,7 +81,7 @@ if api.is_finded("xray") then
s.fields["type"]:value("Xray", translate("Xray"))
end
-o = s:option(ListValue, "xray_protocol", translate("Protocol"))
+o = s:option(ListValue, option_name("protocol"), translate("Protocol"))
o:value("vmess", "Vmess")
o:value("vless", "VLESS")
o:value("http", "HTTP")
@@ -82,128 +91,122 @@ o:value("trojan", "Trojan")
o:value("dokodemo-door", "dokodemo-door")
add_xray_depends(o)
add_v2ray_depends(o)
-o.cfgvalue = rm_prefix_cfgvalue
-o.write = rm_prefix_write
-o = s:option(Value, "xray_port", translate("Listen Port"))
+o = s:option(Value, option_name("port"), translate("Listen Port"))
o.datatype = "port"
add_xray_depends(o)
add_v2ray_depends(o)
-o.cfgvalue = rm_prefix_cfgvalue
-o.write = rm_prefix_write
-o = s:option(Flag, "xray_auth", translate("Auth"))
+o = s:option(Flag, option_name("auth"), translate("Auth"))
o.validate = function(self, value, t)
if value and value == "1" then
- local user_v = s.fields["xray_username"]:formvalue(t) or ""
- local pass_v = s.fields["xray_password"]:formvalue(t) or ""
+ local user_v = s.fields[option_name("username")]:formvalue(t) or ""
+ local pass_v = s.fields[option_name("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
-add_xray_depends(o, { xray_protocol = "socks" })
-add_xray_depends(o, { xray_protocol = "http" })
-add_v2ray_depends(o, { xray_protocol = "socks" })
-add_v2ray_depends(o, { xray_protocol = "http" })
-o.cfgvalue = rm_prefix_cfgvalue
-o.write = rm_prefix_write
+add_xray_depends(o, { [option_name("protocol")] = "socks" })
+add_xray_depends(o, { [option_name("protocol")] = "http" })
+add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
+add_v2ray_depends(o, { [option_name("protocol")] = "http" })
-o = s:option(Value, "xray_username", translate("Username"))
-add_xray_depends(o, { xray_auth = true })
-add_v2ray_depends(o, { xray_auth = true })
-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("auth")] = true })
+add_v2ray_depends(o, { [option_name("auth")] = true })
-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_auth = true })
-add_v2ray_depends(o, { xray_auth = true })
-add_xray_depends(o, { xray_protocol = "shadowsocks" })
-add_v2ray_depends(o, { xray_protocol = "shadowsocks" })
-o.cfgvalue = rm_prefix_cfgvalue
-o.write = rm_prefix_write
+add_xray_depends(o, { [option_name("auth")] = true })
+add_v2ray_depends(o, { [option_name("auth")] = true })
+add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
+add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
-o = s:option(ListValue, "d_protocol", translate("Destination protocol"))
+o = s:option(ListValue, option_name("d_protocol"), translate("Destination protocol"))
o:value("tcp", "TCP")
o:value("udp", "UDP")
o:value("tcp,udp", "TCP,UDP")
-add_v2ray_depends(o, { xray_protocol = "dokodemo-door" })
-add_xray_depends(o, { xray_protocol = "dokodemo-door" })
+add_v2ray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
+add_xray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
-o = s:option(Value, "d_address", translate("Destination address"))
-add_v2ray_depends(o, { xray_protocol = "dokodemo-door" })
-add_xray_depends(o, { xray_protocol = "dokodemo-door" })
+o = s:option(Value, option_name("d_address"), translate("Destination address"))
+add_v2ray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
+add_xray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
-o = s:option(Value, "d_port", translate("Destination port"))
+o = s:option(Value, option_name("d_port"), translate("Destination port"))
o.datatype = "port"
-add_v2ray_depends(o, { xray_protocol = "dokodemo-door" })
-add_xray_depends(o, { xray_protocol = "dokodemo-door" })
+add_v2ray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
+add_xray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
-o = s:option(Value, "decryption", translate("Encrypt Method"))
+o = s:option(Value, option_name("decryption"), translate("Encrypt Method"))
o.default = "none"
-add_v2ray_depends(o, { xray_protocol = "vless" })
-add_xray_depends(o, { xray_protocol = "vless" })
+add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
+add_xray_depends(o, { [option_name("protocol")] = "vless" })
-o = s:option(ListValue, "v_ss_encrypt_method", translate("Encrypt Method"))
-for a, t in ipairs(v_ss_encrypt_method_list) do o:value(t) end
-add_v2ray_depends(o, { xray_protocol = "shadowsocks" })
+o = s:option(ListValue, option_name("v_ss_method"), translate("Encrypt Method"))
+o.not_rewrite = true
+for a, t in ipairs(v_ss_method_list) do o:value(t) end
+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]) == "V2ray" then
+ m:set(section, "method", value)
+ end
end
-o = s:option(ListValue, "x_ss_encrypt_method", translate("Encrypt Method"))
-for a, t in ipairs(x_ss_encrypt_method_list) do o:value(t) end
-add_xray_depends(o, { xray_protocol = "shadowsocks" })
+o = s:option(ListValue, option_name("x_ss_method"), translate("Encrypt Method"))
+o.not_rewrite = true
+for a, t in ipairs(x_ss_method_list) do o:value(t) end
+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" 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" })
+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" })
-o = s:option(ListValue, "ss_network", translate("Transport"))
+o = s:option(ListValue, option_name("ss_network"), translate("Transport"))
o.default = "tcp,udp"
o:value("tcp", "TCP")
o:value("udp", "UDP")
o:value("tcp,udp", "TCP,UDP")
-add_v2ray_depends(o, { xray_protocol = "shadowsocks" })
-add_xray_depends(o, { xray_protocol = "shadowsocks" })
+add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
+add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
-o = s:option(Flag, "udp_forward", translate("UDP Forward"))
+o = s:option(Flag, option_name("udp_forward"), translate("UDP Forward"))
o.default = "1"
o.rmempty = false
-add_v2ray_depends(o, { xray_protocol = "socks" })
-add_xray_depends(o, { xray_protocol = "socks" })
+add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
+add_xray_depends(o, { [option_name("protocol")] = "socks" })
-o = s:option(DynamicList, "xray_uuid", translate("ID") .. "/" .. translate("Password"))
+o = s:option(DynamicList, option_name("uuid"), translate("ID") .. "/" .. translate("Password"))
for i = 1, 3 do
o:value(api.gen_uuid(1))
end
-add_v2ray_depends(o, { xray_protocol = "vmess" })
-add_v2ray_depends(o, { xray_protocol = "vless" })
-add_v2ray_depends(o, { xray_protocol = "trojan" })
-add_xray_depends(o, { xray_protocol = "vmess" })
-add_xray_depends(o, { xray_protocol = "vless" })
-add_xray_depends(o, { xray_protocol = "trojan" })
-o.cfgvalue = rm_prefix_cfgvalue
-o.write = rm_prefix_write
+add_v2ray_depends(o, { [option_name("protocol")] = "vmess" })
+add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
+add_v2ray_depends(o, { [option_name("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")] = "trojan" })
-o = s:option(Flag, "xray_tls", translate("TLS"))
+o = s:option(Flag, option_name("tls"), translate("TLS"))
o.default = 0
o.validate = function(self, value, t)
if value then
if value == "1" then
- local ca = s.fields["xray_tls_certificateFile"]:formvalue(t) or ""
- local key = s.fields["xray_tls_keyFile"]:formvalue(t) or ""
+ local ca = s.fields[option_name("tls_certificateFile")]:formvalue(t) or ""
+ local key = s.fields[option_name("tls_keyFile")]:formvalue(t) or ""
if ca == "" or key == "" then
return nil, translate("Public key and Private key path can not be empty!")
end
@@ -211,48 +214,44 @@ o.validate = function(self, value, t)
return value
end
end
-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, { 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" })
-o.cfgvalue = rm_prefix_cfgvalue
-o.write = rm_prefix_write
+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" })
+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" })
-o = s:option(Value, "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 })
+add_xray_depends(o, { [option_name("protocol")] = "vless", [option_name("tls")] = true })
-o = s:option(ListValue, "alpn", translate("alpn"))
+o = s:option(ListValue, option_name("alpn"), translate("alpn"))
o.default = "h2,http/1.1"
o:value("h2,http/1.1")
o:value("h2")
o:value("http/1.1")
-add_v2ray_depends(o, { xray_tls = true })
-add_xray_depends(o, { xray_tls = true })
+add_v2ray_depends(o, { [option_name("tls")] = true })
+add_xray_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_v2ray_depends(o, { xray_tls = true })
---add_xray_depends(o, { xray_tls = true })
+--add_v2ray_depends(o, { [option_name("tls")] = true })
+--add_xray_depends(o, { [option_name("tls")] = true })
-- [[ TLS部分 ]] --
-o = s:option(FileUpload, "xray_tls_certificateFile", translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
+o = s:option(FileUpload, option_name("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"
-add_v2ray_depends(o, { xray_tls = true })
-add_xray_depends(o, { xray_tls = true })
-o.cfgvalue = rm_prefix_cfgvalue
-o.write = rm_prefix_write
+add_v2ray_depends(o, { [option_name("tls")] = true })
+add_xray_depends(o, { [option_name("tls")] = true })
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@@ -264,12 +263,10 @@ o.validate = function(self, value, t)
return nil
end
-o = s:option(FileUpload, "xray_tls_keyFile", translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
+o = s:option(FileUpload, option_name("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"
-add_v2ray_depends(o, { xray_tls = true })
-add_xray_depends(o, { xray_tls = true })
-o.cfgvalue = rm_prefix_cfgvalue
-o.write = rm_prefix_write
+add_v2ray_depends(o, { [option_name("tls")] = true })
+add_xray_depends(o, { [option_name("tls")] = true })
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@@ -281,7 +278,7 @@ o.validate = function(self, value, t)
return nil
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")
@@ -289,179 +286,171 @@ o:value("h2", "HTTP/2")
o:value("ds", "DomainSocket")
o:value("quic", "QUIC")
o:value("grpc", "gRPC")
-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, { 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, { [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" })
+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" })
-- [[ WebSocket部分 ]]--
-o = s:option(Value, "xray_ws_host", translate("WebSocket Host"))
-add_v2ray_depends(o, { transport = "ws" })
-add_xray_depends(o, { transport = "ws" })
-o.cfgvalue = rm_prefix_cfgvalue
-o.write = rm_prefix_write
+o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
+add_v2ray_depends(o, { [option_name("transport")] = "ws" })
+add_xray_depends(o, { [option_name("transport")] = "ws" })
-o = s:option(Value, "xray_ws_path", translate("WebSocket Path"))
-add_v2ray_depends(o, { transport = "ws" })
-add_xray_depends(o, { transport = "ws" })
-o.cfgvalue = rm_prefix_cfgvalue
-o.write = rm_prefix_write
+o = s:option(Value, option_name("ws_path"), translate("WebSocket Path"))
+add_v2ray_depends(o, { [option_name("transport")] = "ws" })
+add_xray_depends(o, { [option_name("transport")] = "ws" })
-- [[ HTTP/2部分 ]]--
-o = s:option(Value, "xray_h2_host", translate("HTTP/2 Host"))
-add_v2ray_depends(o, { transport = "h2" })
-add_xray_depends(o, { transport = "h2" })
-o.cfgvalue = rm_prefix_cfgvalue
-o.write = rm_prefix_write
+o = s:option(Value, option_name("h2_host"), translate("HTTP/2 Host"))
+add_v2ray_depends(o, { [option_name("transport")] = "h2" })
+add_xray_depends(o, { [option_name("transport")] = "h2" })
-o = s:option(Value, "xray_h2_path", translate("HTTP/2 Path"))
-add_v2ray_depends(o, { transport = "h2" })
-add_xray_depends(o, { transport = "h2" })
-o.cfgvalue = rm_prefix_cfgvalue
-o.write = rm_prefix_write
+o = s:option(Value, option_name("h2_path"), translate("HTTP/2 Path"))
+add_v2ray_depends(o, { [option_name("transport")] = "h2" })
+add_xray_depends(o, { [option_name("transport")] = "h2" })
-- [[ 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_v2ray_depends(o, { transport = "tcp" })
-add_xray_depends(o, { transport = "tcp" })
+add_v2ray_depends(o, { [option_name("transport")] = "tcp" })
+add_xray_depends(o, { [option_name("transport")] = "tcp" })
-- HTTP域名
-o = s:option(DynamicList, "tcp_guise_http_host", translate("HTTP Host"))
-add_v2ray_depends(o, { tcp_guise = "http" })
-add_xray_depends(o, { tcp_guise = "http" })
+o = s:option(DynamicList, option_name("tcp_guise_http_host"), translate("HTTP Host"))
+add_v2ray_depends(o, { [option_name("tcp_guise")] = "http" })
+add_xray_depends(o, { [option_name("tcp_guise")] = "http" })
-- HTTP路径
-o = s:option(DynamicList, "tcp_guise_http_path", translate("HTTP Path"))
-add_v2ray_depends(o, { tcp_guise = "http" })
-add_xray_depends(o, { tcp_guise = "http" })
+o = s:option(DynamicList, option_name("tcp_guise_http_path"), translate("HTTP Path"))
+add_v2ray_depends(o, { [option_name("tcp_guise")] = "http" })
+add_xray_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_v2ray_depends(o, { transport = "mkcp" })
-add_xray_depends(o, { transport = "mkcp" })
+add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
+add_xray_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_v2ray_depends(o, { transport = "mkcp" })
-add_xray_depends(o, { transport = "mkcp" })
+add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
+add_xray_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_v2ray_depends(o, { transport = "mkcp" })
-add_xray_depends(o, { transport = "mkcp" })
+add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
+add_xray_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_v2ray_depends(o, { transport = "mkcp" })
-add_xray_depends(o, { transport = "mkcp" })
+add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
+add_xray_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_v2ray_depends(o, { transport = "mkcp" })
-add_xray_depends(o, { transport = "mkcp" })
+add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
+add_xray_depends(o, { [option_name("transport")] = "mkcp" })
-o = s:option(Flag, "mkcp_congestion", translate("KCP Congestion"))
-add_v2ray_depends(o, { transport = "mkcp" })
-add_xray_depends(o, { transport = "mkcp" })
+o = s:option(Flag, option_name("mkcp_congestion"), translate("KCP Congestion"))
+add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
+add_xray_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_v2ray_depends(o, { transport = "mkcp" })
-add_xray_depends(o, { transport = "mkcp" })
+add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
+add_xray_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_v2ray_depends(o, { transport = "mkcp" })
-add_xray_depends(o, { transport = "mkcp" })
+add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
+add_xray_depends(o, { [option_name("transport")] = "mkcp" })
-o = s:option(Value, "mkcp_seed", translate("KCP Seed"))
-add_v2ray_depends(o, { transport = "mkcp" })
-add_xray_depends(o, { transport = "mkcp" })
+o = s:option(Value, option_name("mkcp_seed"), translate("KCP Seed"))
+add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
+add_xray_depends(o, { [option_name("transport")] = "mkcp" })
-- [[ DomainSocket部分 ]]--
-o = s:option(Value, "ds_path", "Path", translate("A legal file path. This file must not exist before running."))
-add_v2ray_depends(o, { transport = "ds" })
-add_xray_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_v2ray_depends(o, { [option_name("transport")] = "ds" })
+add_xray_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_v2ray_depends(o, { transport = "quic" })
-add_xray_depends(o, { transport = "quic" })
+add_v2ray_depends(o, { [option_name("transport")] = "quic" })
+add_xray_depends(o, { [option_name("transport")] = "quic" })
-o = s:option(Value, "quic_key", translate("Encrypt Method") .. translate("Key"))
-add_v2ray_depends(o, { transport = "quic" })
-add_xray_depends(o, { transport = "quic" })
+o = s:option(Value, option_name("quic_key"), translate("Encrypt Method") .. translate("Key"))
+add_v2ray_depends(o, { [option_name("transport")] = "quic" })
+add_xray_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_v2ray_depends(o, { transport = "quic" })
-add_xray_depends(o, { transport = "quic" })
+add_v2ray_depends(o, { [option_name("transport")] = "quic" })
+add_xray_depends(o, { [option_name("transport")] = "quic" })
-- [[ gRPC部分 ]]--
-o = s:option(Value, "grpc_serviceName", "ServiceName")
-add_v2ray_depends(o, { transport = "grpc" })
-add_xray_depends(o, { transport = "grpc" })
+o = s:option(Value, option_name("grpc_serviceName"), "ServiceName")
+add_v2ray_depends(o, { [option_name("transport")] = "grpc" })
+add_xray_depends(o, { [option_name("transport")] = "grpc" })
-o = s:option(Flag, "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."))
-add_v2ray_depends(o, { transport = "tcp" })
-add_v2ray_depends(o, { transport = "ws" })
-add_xray_depends(o, { transport = "tcp" })
-add_xray_depends(o, { transport = "ws" })
+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."))
+add_v2ray_depends(o, { [option_name("transport")] = "tcp" })
+add_v2ray_depends(o, { [option_name("transport")] = "ws" })
+add_xray_depends(o, { [option_name("transport")] = "tcp" })
+add_xray_depends(o, { [option_name("transport")] = "ws" })
-- [[ Fallback部分 ]]--
-o = s:option(Flag, "fallback", translate("Fallback"))
-add_v2ray_depends(o, { xray_protocol = "vless", transport = "tcp" })
-add_v2ray_depends(o, { xray_protocol = "trojan", transport = "tcp" })
-add_xray_depends(o, { xray_protocol = "vless", transport = "tcp" })
-add_xray_depends(o, { xray_protocol = "trojan", transport = "tcp" })
+o = s:option(Flag, option_name("fallback"), translate("Fallback"))
+add_v2ray_depends(o, { [option_name("protocol")] = "vless", [option_name("transport")] = "tcp" })
+add_v2ray_depends(o, { [option_name("protocol")] = "trojan", [option_name("transport")] = "tcp" })
+add_xray_depends(o, { [option_name("protocol")] = "vless", [option_name("transport")] = "tcp" })
+add_xray_depends(o, { [option_name("protocol")] = "trojan", [option_name("transport")] = "tcp" })
--[[
-o = s:option(Value, "fallback_alpn", "Fallback alpn")
-add_v2ray_depends(o, { fallback = true })
-add_xray_depends(o, { fallback = true })
+o = s:option(Value, option_name("fallback_alpn"), "Fallback alpn")
+add_v2ray_depends(o, { [option_name("fallback")] = true })
+add_xray_depends(o, { [option_name("fallback")] = true })
-o = s:option(Value, "fallback_path", "Fallback path")
-add_v2ray_depends(o, { fallback = true })
-add_xray_depends(o, { fallback = true })
+o = s:option(Value, option_name("fallback_path"), "Fallback path")
+add_v2ray_depends(o, { [option_name("fallback")] = true })
+add_xray_depends(o, { [option_name("fallback")] = true })
-o = s:option(Value, "fallback_dest", "Fallback dest")
-add_v2ray_depends(o, { fallback = true })
-add_xray_depends(o, { fallback = true })
+o = s:option(Value, option_name("fallback_dest"), "Fallback dest")
+add_v2ray_depends(o, { [option_name("fallback")] = true })
+add_xray_depends(o, { [option_name("fallback")] = true })
-o = s:option(Value, "fallback_xver", "Fallback xver")
+o = s:option(Value, option_name("fallback_xver"), "Fallback xver")
o.default = 0
-add_v2ray_depends(o, { fallback = true })
-add_xray_depends(o, { fallback = true })
+add_v2ray_depends(o, { [option_name("fallback")] = true })
+add_xray_depends(o, { [option_name("fallback")] = true })
]]--
-o = s:option(DynamicList, "fallback_list", "Fallback", translate("dest,path"))
-add_v2ray_depends(o, { fallback = true })
-add_xray_depends(o, { fallback = true })
+o = s:option(DynamicList, option_name("fallback_list"), "Fallback", translate("dest,path"))
+add_v2ray_depends(o, { [option_name("fallback")] = true })
+add_xray_depends(o, { [option_name("fallback")] = true })
-o = s:option(Flag, "bind_local", translate("Bind Local"), translate("When selected, it can only be accessed locally, It is recommended to turn on when using reverse proxies or be fallback."))
+o = s:option(Flag, option_name("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed locally, It is recommended to turn on when using reverse proxies or be fallback."))
o.default = "0"
add_v2ray_depends(o)
add_xray_depends(o)
-o = s:option(Flag, "accept_lan", translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!"))
+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.default = "0"
add_v2ray_depends(o)
add_xray_depends(o)
@@ -476,7 +465,7 @@ for k, e in ipairs(api.get_valid_nodes()) do
end
end
-o = s:option(ListValue, "outbound_node", translate("outbound node"))
+o = s:option(ListValue, option_name("outbound_node"), translate("outbound node"))
o:value("nil", translate("Close"))
o:value("_socks", translate("Custom Socks"))
o:value("_http", translate("Custom HTTP"))
@@ -486,51 +475,58 @@ o.default = "nil"
add_v2ray_depends(o)
add_xray_depends(o)
-o = s:option(Value, "outbound_node_address", translate("Address (Support Domain Name)"))
-add_v2ray_depends(o, { outbound_node = "_socks"})
-add_v2ray_depends(o, { outbound_node = "_http"})
-add_xray_depends(o, { outbound_node = "_socks"})
-add_xray_depends(o, { outbound_node = "_http"})
+o = s:option(Value, option_name("outbound_node_address"), translate("Address (Support Domain Name)"))
+add_v2ray_depends(o, { [option_name("outbound_node")] = "_socks"})
+add_v2ray_depends(o, { [option_name("outbound_node")] = "_http"})
+add_xray_depends(o, { [option_name("outbound_node")] = "_socks"})
+add_xray_depends(o, { [option_name("outbound_node")] = "_http"})
-o = s:option(Value, "outbound_node_port", translate("Port"))
+o = s:option(Value, option_name("outbound_node_port"), translate("Port"))
o.datatype = "port"
-add_v2ray_depends(o, { outbound_node = "_socks"})
-add_v2ray_depends(o, { outbound_node = "_http"})
-add_xray_depends(o, { outbound_node = "_socks"})
-add_xray_depends(o, { outbound_node = "_http"})
+add_v2ray_depends(o, { [option_name("outbound_node")] = "_socks"})
+add_v2ray_depends(o, { [option_name("outbound_node")] = "_http"})
+add_xray_depends(o, { [option_name("outbound_node")] = "_socks"})
+add_xray_depends(o, { [option_name("outbound_node")] = "_http"})
-o = s:option(Value, "outbound_node_username", translate("Username"))
-add_v2ray_depends(o, { outbound_node = "_socks"})
-add_v2ray_depends(o, { outbound_node = "_http"})
-add_xray_depends(o, { outbound_node = "_socks"})
-add_xray_depends(o, { outbound_node = "_http"})
+o = s:option(Value, option_name("outbound_node_username"), translate("Username"))
+add_v2ray_depends(o, { [option_name("outbound_node")] = "_socks"})
+add_v2ray_depends(o, { [option_name("outbound_node")] = "_http"})
+add_xray_depends(o, { [option_name("outbound_node")] = "_socks"})
+add_xray_depends(o, { [option_name("outbound_node")] = "_http"})
-o = s:option(Value, "outbound_node_password", translate("Password"))
+o = s:option(Value, option_name("outbound_node_password"), translate("Password"))
o.password = true
-add_v2ray_depends(o, { outbound_node = "_socks"})
-add_v2ray_depends(o, { outbound_node = "_http"})
-add_xray_depends(o, { outbound_node = "_socks"})
-add_xray_depends(o, { outbound_node = "_http"})
+add_v2ray_depends(o, { [option_name("outbound_node")] = "_socks"})
+add_v2ray_depends(o, { [option_name("outbound_node")] = "_http"})
+add_xray_depends(o, { [option_name("outbound_node")] = "_socks"})
+add_xray_depends(o, { [option_name("outbound_node")] = "_http"})
-o = s:option(Value, "outbound_node_iface", translate("Interface"))
+o = s:option(Value, option_name("outbound_node_iface"), translate("Interface"))
o.default = "eth1"
-add_v2ray_depends(o, { outbound_node = "_iface"})
-add_xray_depends(o, { outbound_node = "_iface"})
+add_v2ray_depends(o, { [option_name("outbound_node")] = "_iface"})
+add_xray_depends(o, { [option_name("outbound_node")] = "_iface"})
-o = s:option(Flag, "xray_log", translate("Log"))
+o = s:option(Flag, option_name("log"), translate("Log"))
o.default = "1"
+o.rmempty = false
add_v2ray_depends(o)
add_xray_depends(o)
-o.cfgvalue = rm_prefix_cfgvalue
-o.write = rm_prefix_write
-o = s:option(ListValue, "xray_loglevel", translate("Log Level"))
+o = s:option(ListValue, option_name("loglevel"), translate("Log Level"))
o.default = "warning"
o:value("debug")
o:value("info")
o:value("warning")
o:value("error")
-add_v2ray_depends(o, { xray_log = true })
-add_xray_depends(o, { xray_log = true })
-o.cfgvalue = rm_prefix_cfgvalue
-o.write = rm_prefix_write
+add_v2ray_depends(o, { [option_name("log")] = true })
+add_xray_depends(o, { [option_name("log")] = 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
+end
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/socks.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/socks.lua
index 17a2c9ae9..c1c663c68 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/socks.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/socks.lua
@@ -6,6 +6,8 @@ if not api.is_finded("microsocks") then
return
end
+local type_name = "Socks"
+
local option_prefix = "socks_"
local function option_name(name)
@@ -18,23 +20,32 @@ 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
-- [[ microsocks ]]
-s.fields["type"]:value("Socks", translate("Socks"))
+s.fields["type"]:value(type_name, "Socks")
-o = s:option(Value, "socks_port", "socks" .. translate("Listen Port"))
+o = s:option(Value, option_name("port"), translate("Listen Port"))
o.datatype = "port"
-o = s:option(Flag, "socks_auth", translate("Auth"))
+o = s:option(Flag, option_name("auth"), translate("Auth"))
o.validate = function(self, value, t)
if value and value == "1" then
- local user_v = s.fields["socks_username"]:formvalue(t) or ""
- local pass_v = s.fields["socks_password"]:formvalue(t) or ""
+ local user_v = s.fields[option_name("username")]:formvalue(t) or ""
+ local pass_v = s.fields[option_name("password")]:formvalue(t) or ""
if user_v == "" or pass_v == "" then
return nil, translate("Username and Password must be used together!")
end
@@ -42,14 +53,14 @@ o.validate = function(self, value, t)
return value
end
-o = s:option(Value, "socks_username", translate("Username"))
-o:depends({ socks_auth = true })
+o = s:option(Value, option_name("username"), translate("Username"))
+o:depends({ [option_name("auth")] = true })
-o = s:option(Value, "socks_password", translate("Password"))
+o = s:option(Value, option_name("password"), translate("Password"))
o.password = true
-o:depends({ socks_auth = true })
+o:depends({ [option_name("auth")] = true })
-o = s:option(Flag, "socks_log", translate("Log"))
+o = s:option(Flag, option_name("log"), translate("Log"))
o.default = "1"
for key, value in pairs(s.fields) do
@@ -57,15 +68,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"] = "Socks"
+ deps[index]["type"] = type_name
end
else
- s.fields[key]:depends({ type = "Socks" })
+ s.fields[key]:depends({ type = type_name })
end
end
-end
\ No newline at end of file
+end
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ss-rust.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ss-rust.lua
index 1275e1fff..4b94753bc 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ss-rust.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ss-rust.lua
@@ -6,6 +6,8 @@ if not api.is_finded("ssserver") 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,41 +42,43 @@ 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_port", translate("Listen Port"))
+o = s:option(Value, option_name("port"), translate("Listen 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(ListValue, "ssrust_method", translate("Encrypt Method"))
+o = s:option(ListValue, 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(Flag, "ssrust_tcp_fast_open", "TCP " .. translate("Fast Open"))
+o = s:option(Flag, option_name("tcp_fast_open"), "TCP " .. translate("Fast Open"))
o.default = "0"
-o = s:option(Flag, "ssrust_log", translate("Log"))
+o = s:option(Flag, option_name("log"), translate("Log"))
o.default = "1"
+o.rmempty = false
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-passwall/luasrc/model/cbi/passwall/server/type/ss.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ss.lua
index b232c1598..50afcc828 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ss.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ss.lua
@@ -6,6 +6,8 @@ if not api.is_finded("ss-server") 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
@@ -34,41 +45,43 @@ local ss_encrypt_method_list = {
-- [[ Shadowsocks ]]
-s.fields["type"]:value("SS", translate("Shadowsocks"))
+s.fields["type"]:value(type_name, translate("Shadowsocks"))
-o = s:option(Value, "ss_port", translate("Listen Port"))
+o = s:option(Value, option_name("port"), translate("Listen 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(ListValue, "ss_method", translate("Encrypt Method"))
+o = s:option(ListValue, 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(Flag, "ss_tcp_fast_open", "TCP " .. translate("Fast Open"))
+o = s:option(Flag, option_name("tcp_fast_open"), "TCP " .. translate("Fast Open"))
o.default = "0"
-o = s:option(Flag, "ss_log", translate("Log"))
+o = s:option(Flag, option_name("log"), translate("Log"))
o.default = "1"
+o.rmempty = false
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-passwall/luasrc/model/cbi/passwall/server/type/ssr.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ssr.lua
index 55fa3e25f..72d477982 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ssr.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ssr.lua
@@ -6,6 +6,8 @@ if not api.is_finded("ssr-server") 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,55 +55,57 @@ local ssr_obfs_list = {
-- [[ ShadowsocksR ]]
-s.fields["type"]:value("SSR", translate("ShadowsocksR"))
+s.fields["type"]:value(type_name, translate("ShadowsocksR"))
-o = s:option(Value, "ssr_port", translate("Listen Port"))
+o = s:option(Value, option_name("port"), translate("Listen 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(Flag, "ssr_tcp_fast_open", "TCP " .. translate("Fast Open"))
+o = s:option(Flag, option_name("tcp_fast_open"), "TCP " .. translate("Fast Open"))
o.default = "0"
-o = s:option(Flag, "ssr_udp_forward", translate("UDP Forward"))
+o = s:option(Flag, option_name("udp_forward"), translate("UDP Forward"))
o.default = "1"
o.rmempty = false
-o = s:option(Flag, "ssr_log", translate("Log"))
+o = s:option(Flag, option_name("log"), translate("Log"))
o.default = "1"
+o.rmempty = false
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"] = "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-passwall/luasrc/model/cbi/passwall/server/type/trojan-go.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/trojan-go.lua
index bfaac82eb..fbd1362fc 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/trojan-go.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/trojan-go.lua
@@ -6,6 +6,8 @@ if not api.is_finded("trojan-go") then
return
end
+local type_name = "Trojan-Go"
+
local option_prefix = "trojan_go_"
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,27 +42,27 @@ local encrypt_methods_ss_aead = {
-- [[ Trojan-Go ]]
-s.fields["type"]:value("Trojan-Go", translate("Trojan-Go"))
+s.fields["type"]:value(type_name, "Trojan-Go")
-o = s:option(Value, "trojan_go_port", translate("Listen Port"))
+o = s:option(Value, option_name("port"), translate("Listen Port"))
o.datatype = "port"
-o = s:option(DynamicList, "trojan_go_uuid", translate("ID") .. "/" .. translate("Password"))
+o = s:option(DynamicList, option_name("uuid"), translate("ID") .. "/" .. translate("Password"))
for i = 1, 3 do
o:value(api.gen_uuid(1))
end
-o = s:option(Flag, "trojan_go_tls", translate("TLS"))
+o = s:option(Flag, option_name("tls"), translate("TLS"))
o.default = 0
o.validate = function(self, value, t)
if value then
local type = s.fields["type"]:formvalue(t) or ""
- if value == "0" and type == "Trojan-Go" then
+ if value == "0" and type == type_name then
return nil, translate("Original Trojan only supported 'tls', please choose 'tls'.")
end
if value == "1" then
- local ca = s.fields["trojan_go_tls_certificateFile"]:formvalue(t) or ""
- local key = s.fields["trojan_go_tls_keyFile"]:formvalue(t) or ""
+ local ca = s.fields[option_name("tls_certificateFile")]:formvalue(t) or ""
+ local key = s.fields[option_name("tls_keyFile")]:formvalue(t) or ""
if ca == "" or key == "" then
return nil, translate("Public key and Private key path can not be empty!")
end
@@ -60,9 +71,9 @@ o.validate = function(self, value, t)
end
end
-o = s:option(FileUpload, "trojan_go_tls_certificateFile", translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
+o = s:option(FileUpload, option_name("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({ trojan_go_tls = true })
+o:depends({ [option_name("tls")] = true })
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@@ -74,9 +85,9 @@ o.validate = function(self, value, t)
return nil
end
-o = s:option(FileUpload, "trojan_go_tls_keyFile", translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
+o = s:option(FileUpload, option_name("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({ trojan_go_tls = true })
+o:depends({ [option_name("tls")] = true })
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@@ -88,97 +99,98 @@ o.validate = function(self, value, t)
return nil
end
-o = s:option(Flag, "trojan_go_tls_sessionTicket", translate("Session Ticket"))
+o = s:option(Flag, option_name("tls_sessionTicket"), translate("Session Ticket"))
o.default = "0"
-o:depends({ trojan_go_tls = true })
+o:depends({ [option_name("tls")] = true })
-o = s:option(ListValue, "trojan_go_transport", translate("Transport"))
+o = s:option(ListValue, option_name("transport"), translate("Transport"))
o:value("original", translate("Original"))
o:value("ws", "WebSocket")
o.default = "original"
-o = s:option(ListValue, "trojan_go_plugin_type", translate("Transport Plugin"))
+o = s:option(ListValue, option_name("plugin_type"), translate("Transport Plugin"))
o:value("plaintext", "Plain Text")
o:value("shadowsocks", "ShadowSocks")
o:value("other", "Other")
o.default = "plaintext"
-o:depends({ trojan_go_tls = false, trojan_go_transport = "original" })
+o:depends({ [option_name("tls")] = false, [option_name("transport")] = "original" })
-o = s:option(Value, "trojan_go_plugin_cmd", translate("Plugin Binary"))
+o = s:option(Value, option_name("plugin_cmd"), translate("Plugin Binary"))
o.placeholder = "eg: /usr/bin/v2ray-plugin"
-o:depends({ trojan_go_plugin_type = "shadowsocks" })
-o:depends({ trojan_go_plugin_type = "other" })
+o:depends({ [option_name("plugin_type")] = "shadowsocks" })
+o:depends({ [option_name("plugin_type")] = "other" })
-o = s:option(Value, "trojan_go_plugin_option", translate("Plugin Option"))
+o = s:option(Value, option_name("plugin_option"), translate("Plugin Option"))
o.placeholder = "eg: obfs=http;obfs-host=www.baidu.com"
-o:depends({ trojan_go_plugin_type = "shadowsocks" })
-o:depends({ trojan_go_plugin_type = "other" })
+o:depends({ [option_name("plugin_type")] = "shadowsocks" })
+o:depends({ [option_name("plugin_type")] = "other" })
-o = s:option(DynamicList, "trojan_go_plugin_arg", translate("Plugin Option Args"))
+o = s:option(DynamicList, option_name("plugin_arg"), translate("Plugin Option Args"))
o.placeholder = "eg: [\"-config\", \"test.json\"]"
-o:depends({ trojan_go_plugin_type = "shadowsocks" })
-o:depends({ trojan_go_plugin_type = "other" })
+o:depends({ [option_name("plugin_type")] = "shadowsocks" })
+o:depends({ [option_name("plugin_type")] = "other" })
-o = s:option(Value, "trojan_go_ws_host", translate("WebSocket Host"))
-o:depends({ trojan_go_transport = "ws" })
+o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
+o:depends({ [option_name("transport")] = "ws" })
-o = s:option(Value, "trojan_go_ws_path", translate("WebSocket Path"))
-o:depends({ trojan_go_transport = "ws" })
+o = s:option(Value, option_name("ws_path"), translate("WebSocket Path"))
+o:depends({ [option_name("transport")] = "ws" })
-o = s:option(Flag, "trojan_go_ss_aead", translate("Shadowsocks secondary encryption"))
+o = s:option(Flag, option_name("ss_aead"), translate("Shadowsocks secondary encryption"))
o.default = "0"
-o = s:option(ListValue, "trojan_go_ss_aead_method", translate("Encrypt Method"))
+o = s:option(ListValue, option_name("ss_aead_method"), translate("Encrypt Method"))
for _, v in ipairs(encrypt_methods_ss_aead) do o:value(v, v) end
o.default = "aes-128-gcm"
-o:depends("trojan_go_ss_aead", true)
+o:depends({ [option_name("ss_aead")] = true })
-o = s:option(Value, "trojan_go_ss_aead_pwd", translate("Password"))
+o = s:option(Value, option_name("ss_aead_pwd"), translate("Password"))
o.password = true
-o:depends("trojan_go_ss_aead", true)
+o:depends({ [option_name("ss_aead")] = true })
-o = s:option(Flag, "trojan_go_tcp_fast_open", translate("TCP Fast Open"))
+o = s:option(Flag, option_name("tcp_fast_open"), translate("TCP Fast Open"))
o.default = "0"
-o = s:option(Flag, "trojan_go_remote_enable", translate("Enable Remote"), translate("You can forward to Nginx/Caddy/V2ray/Xray WebSocket and more."))
+o = s:option(Flag, option_name("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, "trojan_go_remote_address", translate("Remote Address"))
+o = s:option(Value, option_name("remote_address"), translate("Remote Address"))
o.default = "127.0.0.1"
-o:depends({ trojan_go_remote_enable = true })
+o:depends({ [option_name("remote_enable")] = true })
-o = s:option(Value, "trojan_go_remote_port", translate("Remote Port"))
+o = s:option(Value, option_name("remote_port"), translate("Remote Port"))
o.datatype = "port"
o.default = "80"
-o:depends({ trojan_go_remote_enable = true })
+o:depends({ [option_name("remote_enable")] = true })
-o = s:option(Flag, "trojan_go_log", translate("Log"))
+o = s:option(Flag, option_name("log"), translate("Log"))
o.default = "1"
-o = s:option(ListValue, "trojan_go_loglevel", translate("Log Level"))
+o = s:option(ListValue, option_name("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({ trojan_go_log = true })
+o:depends({ [option_name("log")] = 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
local deps = s.fields[key].deps
if #deps > 0 then
for index, value in ipairs(deps) do
- deps[index]["type"] = "Trojan-Go"
+ deps[index]["type"] = type_name
end
else
- s.fields[key]:depends({ type = "Trojan-Go" })
+ s.fields[key]:depends({ type = type_name })
end
end
end
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/trojan-plus.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/trojan-plus.lua
index 1515a9f01..09a7636a2 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/trojan-plus.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/trojan-plus.lua
@@ -6,6 +6,8 @@ if not api.is_finded("trojan-plus") then
return
end
+local type_name = "Trojan-Plus"
+
local option_prefix = "trojan_plus_"
local function option_name(name)
@@ -18,34 +20,43 @@ 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
-- [[ Trojan-Plus ]]
-s.fields["type"]:value("Trojan-Plus", translate("Trojan-Plus"))
+s.fields["type"]:value(type_name, "Trojan-Plus")
-o = s:option(Value, "trojan_plus_port", translate("Listen Port"))
+o = s:option(Value, option_name("port"), translate("Listen Port"))
o.datatype = "port"
-o = s:option(DynamicList, "trojan_plus_uuid", translate("ID") .. "/" .. translate("Password"))
+o = s:option(DynamicList, option_name("uuid"), translate("ID") .. "/" .. translate("Password"))
for i = 1, 3 do
o:value(api.gen_uuid(1))
end
-o = s:option(Flag, "trojan_plus_tls", translate("TLS"))
+o = s:option(Flag, option_name("tls"), translate("TLS"))
o.default = 0
o.validate = function(self, value, t)
if value then
local type = s.fields["type"]:formvalue(t) or ""
- if value == "0" and type == "Trojan-Plus" then
+ if value == "0" and type == type_name then
return nil, translate("Original Trojan only supported 'tls', please choose 'tls'.")
end
if value == "1" then
- local ca = s.fields["trojan_plus_tls_certificateFile"]:formvalue(t) or ""
- local key = s.fields["trojan_plus_tls_keyFile"]:formvalue(t) or ""
+ local ca = s.fields[option_name("tls_certificateFile")]:formvalue(t) or ""
+ local key = s.fields[option_name("tls_keyFile")]:formvalue(t) or ""
if ca == "" or key == "" then
return nil, translate("Public key and Private key path can not be empty!")
end
@@ -54,9 +65,9 @@ o.validate = function(self, value, t)
end
end
-o = s:option(FileUpload, "trojan_plus_tls_certificateFile", translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
+o = s:option(FileUpload, option_name("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({ trojan_plus_tls = true })
+o:depends({ [option_name("tls")] = true })
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@@ -68,9 +79,9 @@ o.validate = function(self, value, t)
return nil
end
-o = s:option(FileUpload, "trojan_plus_tls_keyFile", translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
+o = s:option(FileUpload, option_name("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({ trojan_plus_tls = true })
+o:depends({ [option_name("tls")] = true })
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@@ -82,52 +93,53 @@ o.validate = function(self, value, t)
return nil
end
-o = s:option(Flag, "trojan_plus_tls_sessionTicket", translate("Session Ticket"))
+o = s:option(Flag, option_name("tls_sessionTicket"), translate("Session Ticket"))
o.default = "0"
-o:depends({ trojan_plus_tls = true })
+o:depends({ [option_name("tls")] = true })
-o = s:option(Flag, "trojan_plus_tcp_fast_open", translate("TCP Fast Open"))
+o = s:option(Flag, option_name("tcp_fast_open"), translate("TCP Fast Open"))
o.default = "0"
-o = s:option(Flag, "trojan_plus_remote_enable", translate("Enable Remote"), translate("You can forward to Nginx/Caddy/V2ray/Xray WebSocket and more."))
+o = s:option(Flag, option_name("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, "trojan_plus_remote_address", translate("Remote Address"))
+o = s:option(Value, option_name("remote_address"), translate("Remote Address"))
o.default = "127.0.0.1"
-o:depends({ trojan_plus_remote_enable = true })
+o:depends({ [option_name("remote_enable")] = true })
-o = s:option(Value, "trojan_plus_remote_port", translate("Remote Port"))
+o = s:option(Value, option_name("remote_port"), translate("Remote Port"))
o.datatype = "port"
o.default = "80"
-o:depends({ trojan_plus_remote_enable = true })
+o:depends({ [option_name("remote_enable")] = true })
-o = s:option(Flag, "trojan_plus_log", translate("Log"))
+o = s:option(Flag, option_name("log"), translate("Log"))
o.default = "1"
-o = s:option(ListValue, "trojan_plus_loglevel", translate("Log Level"))
+o = s:option(ListValue, option_name("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({ trojan_plus_log = true })
+o:depends({ [option_name("log")] = 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
local deps = s.fields[key].deps
if #deps > 0 then
for index, value in ipairs(deps) do
- deps[index]["type"] = "Trojan-Plus"
+ deps[index]["type"] = type_name
end
else
- s.fields[key]:depends({ type = "Trojan-Plus" })
+ s.fields[key]:depends({ type = type_name })
end
end
end
diff --git a/luci-app-passwall/luasrc/passwall/api.lua b/luci-app-passwall/luasrc/passwall/api.lua
index b8d2af117..d3c508225 100644
--- a/luci-app-passwall/luasrc/passwall/api.lua
+++ b/luci-app-passwall/luasrc/passwall/api.lua
@@ -397,8 +397,12 @@ function get_customed_path(e)
return uci_get_type("global_app", e .. "_file")
end
+function finded(e)
+ return luci.sys.exec('echo -n $(type -t -p "/bin/%s" -p "/usr/bin/%s" -p "%s" "%s" | head -n1)' % {e, e, get_customed_path(e), e})
+end
+
function is_finded(e)
- return luci.sys.exec('type -t -p "/bin/%s" -p "/usr/bin/%s" -p "%s" "%s"' % {e, e, get_customed_path(e), e}) ~= "" and true or false
+ return finded(e) ~= "" and true or false
end
function clone(org)
diff --git a/luci-app-passwall/po/zh-cn/passwall.po b/luci-app-passwall/po/zh-cn/passwall.po
index 0af31cb2d..63634e078 100644
--- a/luci-app-passwall/po/zh-cn/passwall.po
+++ b/luci-app-passwall/po/zh-cn/passwall.po
@@ -625,17 +625,14 @@ msgstr "劫持ICMP (PING)"
msgid "Hijacking ICMPv6 (IPv6 PING)"
msgstr "劫持ICMPv6 (IPv6 PING)"
-msgid "Sniffing (V2Ray/Xray)"
-msgstr "流量嗅探 (V2ray/Xray)"
+msgid "Sniffing"
+msgstr "流量嗅探"
-msgid "When using the V2ray/Xray shunt, must be enabled, otherwise the shunt will invalid."
-msgstr "使用 V2Ray/Xray 分流时,必须启用,否则分流将无效。"
+msgid "When using the shunt, must be enabled, otherwise the shunt will invalid."
+msgstr "使用分流时,必须启用,否则分流将无效。"
-msgid "Sniffing Route Only (Xray)"
-msgstr "流量嗅探只供路由使用 (Xray)"
-
-msgid "When enabled, the server not will resolve the domain name again."
-msgstr "启用后,服务器不会再次解析域名。"
+msgid "Sniffing Route Only"
+msgstr "流量嗅探只供路由使用"
msgid "TCP Proxy Way"
msgstr "TCP 代理方式"
@@ -1441,11 +1438,11 @@ msgstr "初始窗口大小"
msgid "No Sniffing Lists"
msgstr "不进行流量嗅探的域名列表"
-msgid "Hosts added into No Sniffing Lists will not resolve again on server (Xray only)."
-msgstr "加入的域名不会再次在服务器解析(仅适用于Xray)。"
+msgid "Hosts added into No Sniffing Lists will not resolve again on server."
+msgstr "加入的域名不会再次在服务器解析。"
-msgid "Buffer Size (Xray)"
-msgstr "缓冲区大小(Xray)"
+msgid "Buffer Size"
+msgstr "缓冲区大小"
msgid "Buffer size for every connection (kB)"
msgstr "每一个连接的缓冲区大小(kB)"
diff --git a/luci-app-passwall/root/etc/uci-defaults/luci-passwall b/luci-app-passwall/root/etc/uci-defaults/luci-passwall
index cc39c00a2..a862da154 100755
--- a/luci-app-passwall/root/etc/uci-defaults/luci-passwall
+++ b/luci-app-passwall/root/etc/uci-defaults/luci-passwall
@@ -27,8 +27,23 @@ uci -q batch <<-EOF >/dev/null
commit uhttpd
EOF
-[ ! -s "/etc/config/passwall" ] && cp -f /usr/share/passwall/0_default_config /etc/config/passwall
+
touch /etc/config/passwall_show >/dev/null 2>&1
+[ ! -s "/etc/config/passwall" ] && cp -f /usr/share/passwall/0_default_config /etc/config/passwall
+
+global_xray=$(uci -q get passwall.@global_xray[0])
+[ -z "${global_xray}" ] && {
+ cfgid=$(uci add passwall global_xray)
+ uci -q set passwall.${cfgid}.sniffing=$(uci -q get passwall.@global_forwarding[0].sniffing || echo "1")
+ uci -q set passwall.${cfgid}.route_only=$(uci -q get passwall.@global_forwarding[0].route_only || echo "0")
+ uci -q set passwall.${cfgid}.buffer_size=$(uci -q get passwall.@global_forwarding[0].buffer_size || echo "")
+
+ uci -q delete passwall.@global_forwarding[0].sniffing
+ uci -q delete passwall.@global_forwarding[0].route_only
+ uci -q delete passwall.@global_forwarding[0].buffer_size
+ uci -q commit passwall
+}
+
rm -f /tmp/luci-indexcache
rm -rf /tmp/luci-modulecache/
killall -HUP rpcd 2>/dev/null
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 913e9f25e..f21f0ecb1 100644
--- a/luci-app-passwall/root/usr/share/passwall/0_default_config
+++ b/luci-app-passwall/root/usr/share/passwall/0_default_config
@@ -38,6 +38,8 @@ config global_forwarding
option use_nft '0'
option tcp_proxy_way 'redirect'
option ipv6_tproxy '0'
+
+config global_xray
option sniffing '1'
option route_only '0'