diff --git a/luci-app-passwall/luasrc/controller/passwall.lua b/luci-app-passwall/luasrc/controller/passwall.lua
index 831941c..91b8c1a 100644
--- a/luci-app-passwall/luasrc/controller/passwall.lua
+++ b/luci-app-passwall/luasrc/controller/passwall.lua
@@ -77,10 +77,12 @@ function index()
entry({"admin", "services", appname, "connect_status"}, call("connect_status")).leaf = true
entry({"admin", "services", appname, "ping_node"}, call("ping_node")).leaf = true
entry({"admin", "services", appname, "urltest_node"}, call("urltest_node")).leaf = true
+ entry({"admin", "services", appname, "add_node"}, call("add_node")).leaf = true
entry({"admin", "services", appname, "set_node"}, call("set_node")).leaf = true
entry({"admin", "services", appname, "copy_node"}, call("copy_node")).leaf = true
entry({"admin", "services", appname, "clear_all_nodes"}, call("clear_all_nodes")).leaf = true
entry({"admin", "services", appname, "delete_select_nodes"}, call("delete_select_nodes")).leaf = true
+ entry({"admin", "services", appname, "get_node"}, call("get_node")).leaf = true
entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true
entry({"admin", "services", appname, "subscribe_del_node"}, call("subscribe_del_node")).leaf = true
entry({"admin", "services", appname, "subscribe_del_all"}, call("subscribe_del_all")).leaf = true
@@ -397,6 +399,21 @@ function urltest_node()
http_write_json(e)
end
+function add_node()
+ local redirect = http.formvalue("redirect")
+
+ local uuid = api.gen_short_uuid()
+ uci:section(appname, "nodes", uuid)
+
+ if redirect == "1" then
+ api.uci_save(uci, appname)
+ http.redirect(api.url("node_config", uuid))
+ else
+ api.uci_save(uci, appname, true, true)
+ http_write_json({result = uuid})
+ end
+end
+
function set_node()
local protocol = http.formvalue("protocol")
local section = http.formvalue("section")
@@ -420,7 +437,7 @@ function copy_node()
end)
end
end
- uci:delete(appname, uuid, "add_from")
+ uci:delete(appname, uuid, "group")
uci:set(appname, uuid, "add_mode", 1)
api.uci_save(uci, appname)
http.redirect(api.url("node_config", uuid))
@@ -458,6 +475,7 @@ end
function delete_select_nodes()
local ids = http.formvalue("ids")
+ local redirect = http.formvalue("redirect")
string.gsub(ids, '[^' .. "," .. ']+', function(w)
if (uci:get(appname, "@global[0]", "tcp_node") or "") == w then
uci:delete(appname, '@global[0]', "tcp_node")
@@ -532,10 +550,10 @@ function delete_select_nodes()
end
end)
if (uci:get(appname, w, "add_mode") or "0") == "2" then
- local add_from = uci:get(appname, w, "add_from") or ""
- if add_from ~= "" then
+ local group = uci:get(appname, w, "group") or ""
+ if group ~= "" then
uci:foreach(appname, "subscribe_list", function(t)
- if t["remark"] == add_from then
+ if t["remark"] == group then
uci:delete(appname, t[".name"], "md5")
end
end)
@@ -543,7 +561,40 @@ function delete_select_nodes()
end
uci:delete(appname, w)
end)
- api.uci_save(uci, appname, true, true)
+ if redirect == "1" then
+ api.uci_save(uci, appname)
+ http.redirect(api.url("node_list"))
+ else
+ api.uci_save(uci, appname, true, true)
+ end
+end
+
+
+function get_node()
+ local id = http.formvalue("id")
+ local result = {}
+ local show_node_info = api.uci_get_type("@global_other[0]", "show_node_info", "0")
+
+ function add_is_ipv6_key(o)
+ if o and o.address and show_node_info == "1" then
+ local f = api.get_ipv6_full(o.address)
+ if f ~= "" then
+ o.ipv6 = true
+ o.full_address = f
+ end
+ end
+ end
+
+ if id then
+ result = uci:get_all(appname, id)
+ add_is_ipv6_key(result)
+ else
+ uci:foreach(appname, "nodes", function(t)
+ add_is_ipv6_key(t)
+ result[#result + 1] = t
+ end)
+ end
+ http_write_json(result)
end
function update_rules()
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua
index b6a3511..4d713e6 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua
@@ -21,6 +21,21 @@ o = s:option(Value, "remarks", translate("Node Remarks"))
o.default = translate("Remarks")
o.rmempty = false
+o = s:option(Value, "group", translate("Group Name"))
+o.default = ""
+o:value("", translate("default"))
+local groups = {}
+m.uci:foreach(appname, "nodes", function(s)
+ if s[".name"] ~= arg[1] then
+ if s.group and s.group ~= "" then
+ groups[s.group] = true
+ end
+ end
+end)
+for k, v in pairs(groups) do
+ o:value(k)
+end
+
o = s:option(ListValue, "type", translate("Type"))
if api.is_finded("ipt2socks") then
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua
index 229cd30..8311476 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua
@@ -20,221 +20,6 @@ o.default = "0"
-- [[ Add the node via the link ]]--
s:append(Template(appname .. "/node_list/link_add_node"))
-local auto_detection_time = m:get("@global_other[0]", "auto_detection_time") or "0"
-local show_node_info = m:get("@global_other[0]", "show_node_info") or "0"
-
--- [[ Node List ]]--
-s = m:section(TypedSection, "nodes")
-s.anonymous = true
-s.addremove = true
-s.template = "cbi/tblsection"
-s.extedit = api.url("node_config", "%s")
-function s.create(e, t)
- local uuid = api.gen_short_uuid()
- t = uuid
- TypedSection.create(e, t)
- luci.http.redirect(e.extedit:format(t))
-end
-
-function s.remove(e, t)
- m.uci:foreach(appname, "socks", function(s)
- if s["node"] == t then
- m:del(s[".name"])
- end
- for k, v in ipairs(m:get(s[".name"], "autoswitch_backup_node") or {}) do
- if v and v == t then
- sys.call(string.format("uci -q del_list %s.%s.autoswitch_backup_node='%s'", appname, s[".name"], v))
- end
- end
- end)
- m.uci:foreach(appname, "haproxy_config", function(s)
- if s["lbss"] and s["lbss"] == t then
- m:del(s[".name"])
- end
- end)
- m.uci:foreach(appname, "acl_rule", function(s)
- if s["tcp_node"] and s["tcp_node"] == t then
- m:set(s[".name"], "tcp_node", "default")
- end
- if s["udp_node"] and s["udp_node"] == t then
- m:set(s[".name"], "udp_node", "default")
- end
- end)
- m.uci:foreach(appname, "nodes", function(s)
- if s["preproxy_node"] == t then
- m:del(s[".name"], "preproxy_node")
- m:del(s[".name"], "chain_proxy")
- end
- if s["to_node"] == t then
- m:del(s[".name"], "to_node")
- m:del(s[".name"], "chain_proxy")
- end
- local list_name = s["urltest_node"] and "urltest_node" or (s["balancing_node"] and "balancing_node")
- if list_name then
- local nodes = m.uci:get_list(appname, s[".name"], list_name)
- if nodes then
- local changed = false
- local new_nodes = {}
- for _, node in ipairs(nodes) do
- if node ~= t then
- table.insert(new_nodes, node)
- else
- changed = true
- end
- end
- if changed then
- m.uci:set_list(appname, s[".name"], list_name, new_nodes)
- end
- end
- end
- if s["fallback_node"] == t then
- m:del(s[".name"], "fallback_node")
- end
- end)
- m.uci:foreach(appname, "subscribe_list", function(s)
- if s["preproxy_node"] == t then
- m:del(s[".name"], "preproxy_node")
- m:del(s[".name"], "chain_proxy")
- end
- if s["to_node"] == t then
- m:del(s[".name"], "to_node")
- m:del(s[".name"], "chain_proxy")
- end
- end)
- if (m:get(t, "add_mode") or "0") == "2" then
- local add_from = m:get(t, "add_from") or ""
- if add_from ~= "" then
- m.uci:foreach(appname, "subscribe_list", function(s)
- if s["remark"] == add_from then
- m:del(s[".name"], "md5")
- end
- end)
- end
- end
- TypedSection.remove(e, t)
- local new_node = ""
- local node0 = m:get("@nodes[0]") or nil
- if node0 then
- new_node = node0[".name"]
- end
- if (m:get("@global[0]", "tcp_node") or "") == t then
- m:set('@global[0]', "tcp_node", new_node)
- end
- if (m:get("@global[0]", "udp_node") or "") == t then
- m:set('@global[0]', "udp_node", new_node)
- end
-end
-
-s.sortable = true
--- 简洁模式
-o = s:option(DummyValue, "add_from", "")
-o.cfgvalue = function(t, n)
- local v = Value.cfgvalue(t, n)
- if v and v ~= '' then
- local group = m:get(n, "group") or ""
- if group ~= "" then
- v = v .. " " .. group
- end
- return v
- else
- return ''
- end
-end
-o = s:option(DummyValue, "remarks", translate("Remarks"))
-o.rawhtml = true
-o.cfgvalue = function(t, n)
- local str = ""
- local is_sub = m:get(n, "is_sub") or ""
- local group = m:get(n, "group") or ""
- local remarks = m:get(n, "remarks") or ""
- local type = m:get(n, "type") or ""
- str = str .. string.format("", appname, n, type)
- if type == "sing-box" or type == "Xray" then
- local protocol = m:get(n, "protocol")
- if protocol == "_balancing" then
- protocol = translate("Balancing")
- elseif protocol == "_urltest" then
- protocol = "URLTest"
- elseif protocol == "_shunt" then
- protocol = translate("Shunt")
- elseif protocol == "vmess" then
- protocol = "VMess"
- elseif protocol == "vless" then
- protocol = "VLESS"
- elseif protocol == "shadowsocks" then
- protocol = "SS"
- elseif protocol == "shadowsocksr" then
- protocol = "SSR"
- elseif protocol == "wireguard" then
- protocol = "WG"
- elseif protocol == "hysteria" then
- protocol = "HY"
- elseif protocol == "hysteria2" then
- protocol = "HY2"
- elseif protocol == "anytls" then
- protocol = "AnyTLS"
- elseif protocol == "ssh" then
- protocol = "SSH"
- else
- protocol = protocol:gsub("^%l",string.upper)
- end
- if type == "sing-box" then type = "Sing-Box" end
- type = type .. " " .. protocol
- end
- local address = m:get(n, "address") or ""
- local port = m:get(n, "port") or ""
- local port_s = (port ~= "") and port or m:get(n, "hysteria_hop") or m:get(n, "hysteria2_hop") or ""
- str = str .. translate(type) .. ":" .. remarks
- if address ~= "" and port_s ~= "" then
- port_s = port_s:gsub(":", "-")
- if show_node_info == "1" then
- if datatypes.ip6addr(address) then
- str = str .. string.format("([%s]:%s)", address, port_s)
- else
- str = str .. string.format("(%s:%s)", address, port_s)
- end
- end
- end
- str = str .. string.format("", appname, n, address)
- str = str .. string.format("", appname, n, port)
- return str
-end
-
----- Ping
-o = s:option(DummyValue, "ping", "Ping")
-o.width = "8%"
-o.rawhtml = true
-o.cfgvalue = function(t, n)
- local result = "---"
- if auto_detection_time ~= "icmp" then
- result = string.format('%s', n, translate("Test"))
- else
- result = string.format('---', n)
- end
- return result
-end
-
----- TCP Ping
-o = s:option(DummyValue, "tcping", "TCPing")
-o.width = "8%"
-o.rawhtml = true
-o.cfgvalue = function(t, n)
- local result = "---"
- if auto_detection_time ~= "tcping" then
- result = string.format('%s', n, translate("Test"))
- else
- result = string.format('---', n)
- end
- return result
-end
-
-o = s:option(DummyValue, "_url_test", translate("URL Test"))
-o.width = "8%"
-o.rawhtml = true
-o.cfgvalue = function(t, n)
- return string.format('%s', n, translate("Test"))
-end
-
m:append(Template(appname .. "/node_list/node_list"))
return m
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua
index c194d78..a2d3694 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua
@@ -190,7 +190,7 @@ o.cfgvalue = function(t, n)
str = str ~= "" and "
" .. str or ""
local num = 0
m.uci:foreach(appname, "nodes", function(s)
- if s["add_from"] ~= "" and s["add_from"] == remark then
+ if s["group"] ~= "" and s["group"] == remark then
num = num + 1
end
end)
diff --git a/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm b/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm
index 5acf53f..1df9c78 100644
--- a/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm
+++ b/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm
@@ -79,6 +79,10 @@ local api = require "luci.passwall.api"
}
}
+ function add_new_node() {
+ window.location.href = '<%=api.url("add_node")%>?redirect=1';
+ }
+
//]]>
@@ -99,15 +103,14 @@ local api = require "luci.passwall.api"