update 2026-08-15 00:44:02
No files matched your search
@@ -10,7 +10,7 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=8d37150fd674731c4a5931cb82937d3c57a09301
|
||||
PKG_SOURCE_VERSION:=04569ccae1bc6c926e59da5c70949010ffb55ba9
|
||||
PKG_SOURCE_URL:=https://github.com/olicesx/dae.git
|
||||
PKG_MIRROR_HASH:=skip
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 319 KiB |
|
After Width: | Height: | Size: 389 KiB |
|
Before Width: | Height: | Size: 640 KiB |
|
Before Width: | Height: | Size: 550 KiB |
|
Before Width: | Height: | Size: 547 KiB |
|
Before Width: | Height: | Size: 659 KiB |
|
Before Width: | Height: | Size: 650 KiB |
@@ -4,8 +4,10 @@
|
||||
|
||||
module("luci.controller.passwall", package.seeall)
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = "passwall" -- not available
|
||||
local uci = api.uci -- in funtion index()
|
||||
local appname = api.appname -- not available
|
||||
local c_config = api.c_config -- not available
|
||||
local s_config = api.s_config -- not available
|
||||
local uci = api.uci -- in funtion index()
|
||||
local fs = api.fs
|
||||
local http = require "luci.http"
|
||||
local util = require "luci.util"
|
||||
@@ -20,14 +22,16 @@ function index()
|
||||
else return end
|
||||
end
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = "passwall" -- global definitions not available
|
||||
local uci = api.uci -- in function index()
|
||||
local appname = api.appname -- global definitions not available
|
||||
local c_config = api.c_config -- not available
|
||||
local s_config = api.s_config -- not available
|
||||
local uci = api.uci -- in function index()
|
||||
local fs = api.fs
|
||||
entry({"admin", "services", appname}).dependent = true
|
||||
entry({"admin", "services", appname, "show"}, call("show_menu")).leaf = true
|
||||
entry({"admin", "services", appname, "hide"}, call("hide_menu")).leaf = true
|
||||
local e
|
||||
if uci:get(appname, "@global[0]", "hide_from_luci") ~= "1" then
|
||||
if uci:get(c_config, "@global[0]", "hide_from_luci") ~= "1" then
|
||||
e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), _("Pass Wall"), -1)
|
||||
else
|
||||
e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), nil, -1)
|
||||
@@ -140,7 +144,7 @@ local function http_write_json_error(data)
|
||||
end
|
||||
|
||||
function reset_config()
|
||||
uci:revert(appname)
|
||||
uci:revert(c_config)
|
||||
luci.sys.call("echo '' > /tmp/log/passwall.log")
|
||||
luci.sys.call('/etc/init.d/passwall stop')
|
||||
if luci.sys.call('[ -s "/usr/share/passwall/0_default_config" ]') == 0 then
|
||||
@@ -152,14 +156,14 @@ function reset_config()
|
||||
end
|
||||
|
||||
function show_menu()
|
||||
api.sh_uci_del(appname, "@global[0]", "hide_from_luci", true)
|
||||
api.sh_uci_del(c_config, "@global[0]", "hide_from_luci", true)
|
||||
luci.sys.call("rm -rf /tmp/luci-*")
|
||||
luci.sys.call("/etc/init.d/rpcd restart >/dev/null")
|
||||
http.redirect(api.url())
|
||||
end
|
||||
|
||||
function hide_menu()
|
||||
api.sh_uci_set(appname, "@global[0]", "hide_from_luci", "1", true)
|
||||
api.sh_uci_set(c_config, "@global[0]", "hide_from_luci", "1", true)
|
||||
luci.sys.call("rm -rf /tmp/luci-*")
|
||||
luci.sys.call("/etc/init.d/rpcd restart >/dev/null")
|
||||
http.redirect(luci.dispatcher.build_url("admin", "status", "overview"))
|
||||
@@ -195,10 +199,10 @@ function socks_autoswitch_add_node()
|
||||
local id = http.formvalue("id")
|
||||
local key = http.formvalue("key")
|
||||
if id and id ~= "" and key and key ~= "" then
|
||||
uci:set(appname, id, "enable_autoswitch", "1")
|
||||
local new_list = uci:get(appname, id, "autoswitch_backup_node") or {}
|
||||
uci:set(c_config, id, "enable_autoswitch", "1")
|
||||
local new_list = uci:get(c_config, id, "autoswitch_backup_node") or {}
|
||||
for i = #new_list, 1, -1 do
|
||||
if (uci:get(appname, new_list[i], "remarks") or ""):find(key) then
|
||||
if (uci:get(c_config, new_list[i], "remarks") or ""):find(key) then
|
||||
table.remove(new_list, i)
|
||||
end
|
||||
end
|
||||
@@ -207,8 +211,8 @@ function socks_autoswitch_add_node()
|
||||
table.insert(new_list, e.id)
|
||||
end
|
||||
end
|
||||
uci:set_list(appname, id, "autoswitch_backup_node", new_list)
|
||||
api.uci_save(uci, appname)
|
||||
uci:set_list(c_config, id, "autoswitch_backup_node", new_list)
|
||||
api.uci_save(uci, c_config)
|
||||
end
|
||||
http.redirect(api.url("socks_config", id))
|
||||
end
|
||||
@@ -217,15 +221,15 @@ function socks_autoswitch_remove_node()
|
||||
local id = http.formvalue("id")
|
||||
local key = http.formvalue("key")
|
||||
if id and id ~= "" and key and key ~= "" then
|
||||
uci:set(appname, id, "enable_autoswitch", "1")
|
||||
local new_list = uci:get(appname, id, "autoswitch_backup_node") or {}
|
||||
uci:set(c_config, id, "enable_autoswitch", "1")
|
||||
local new_list = uci:get(c_config, id, "autoswitch_backup_node") or {}
|
||||
for i = #new_list, 1, -1 do
|
||||
if (uci:get(appname, new_list[i], "remarks") or ""):find(key) then
|
||||
if (uci:get(c_config, new_list[i], "remarks") or ""):find(key) then
|
||||
table.remove(new_list, i)
|
||||
end
|
||||
end
|
||||
uci:set_list(appname, id, "autoswitch_backup_node", new_list)
|
||||
api.uci_save(uci, appname)
|
||||
uci:set_list(c_config, id, "autoswitch_backup_node", new_list)
|
||||
api.uci_save(uci, c_config)
|
||||
end
|
||||
http.redirect(api.url("socks_config", id))
|
||||
end
|
||||
@@ -389,7 +393,7 @@ function socks_status()
|
||||
local id = http.formvalue("id")
|
||||
e.index = index
|
||||
e.socks_status = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v -E 'grep|acl/|acl_' | grep '%s/bin/' | grep '%s' > /dev/null", appname, id)) == 0
|
||||
local use_http = uci:get(appname, id, "http_port") or 0
|
||||
local use_http = uci:get(c_config, id, "http_port") or 0
|
||||
e.use_http = 0
|
||||
if tonumber(use_http) > 0 then
|
||||
e.use_http = 1
|
||||
@@ -481,9 +485,9 @@ function update_config()
|
||||
local data_t = jsonParse(data) or {}
|
||||
if next(data_t) then
|
||||
for k, v in pairs(data_t) do
|
||||
uci:set(appname, id, k, v)
|
||||
uci:set(c_config, id, k, v)
|
||||
end
|
||||
api.uci_save(uci, appname)
|
||||
api.uci_save(uci, c_config)
|
||||
http_write_json_ok()
|
||||
return
|
||||
end
|
||||
@@ -495,20 +499,20 @@ function add_node()
|
||||
local redirect = http.formvalue("redirect")
|
||||
|
||||
local uid = api.gen_random_char()
|
||||
uci:section(appname, "nodes", uid)
|
||||
uci:section(c_config, "nodes", uid)
|
||||
|
||||
local group = http.formvalue("group")
|
||||
if group and group ~= "default" then
|
||||
uci:set(appname, uid, "group", group)
|
||||
uci:set(c_config, uid, "group", group)
|
||||
end
|
||||
|
||||
uci:set(appname, uid, "type", "Socks")
|
||||
uci:set(c_config, uid, "type", "Socks")
|
||||
|
||||
if redirect == "1" then
|
||||
api.uci_save(uci, appname)
|
||||
api.uci_save(uci, c_config)
|
||||
http.redirect(api.url("node_config", uid))
|
||||
else
|
||||
api.uci_save(uci, appname, true, true)
|
||||
api.uci_save(uci, c_config, true, true)
|
||||
http_write_json({result = uid})
|
||||
end
|
||||
end
|
||||
@@ -516,82 +520,80 @@ end
|
||||
function set_node()
|
||||
local protocol = http.formvalue("protocol")
|
||||
local section = http.formvalue("section")
|
||||
uci:set(appname, "@global[0]", protocol .. "_node", section)
|
||||
uci:set(c_config, "@global[0]", protocol .. "_node", section)
|
||||
if protocol == "tcp" then
|
||||
local node_protocol = uci:get(appname, section, "protocol")
|
||||
local node_protocol = uci:get(c_config, section, "protocol")
|
||||
if node_protocol == "_shunt" then
|
||||
local type = uci:get(appname, section, "type")
|
||||
local dns_shunt = uci:get(appname, "@global[0]", "dns_shunt")
|
||||
local type = uci:get(c_config, section, "type")
|
||||
local dns_shunt = uci:get(c_config, "@global[0]", "dns_shunt")
|
||||
local dns_key = (dns_shunt == "smartdns") and "smartdns_dns_mode" or "dns_mode"
|
||||
local dns_mode = uci:get(appname, "@global[0]", dns_key)
|
||||
local dns_mode = uci:get(c_config, "@global[0]", dns_key)
|
||||
local new_dns_mode = (type == "Xray") and "xray" or "sing-box"
|
||||
if dns_mode ~= new_dns_mode then
|
||||
uci:set(appname, "@global[0]", dns_key, new_dns_mode)
|
||||
uci:set(appname, "@global[0]", "v2ray_dns_mode", "tcp")
|
||||
uci:set(c_config, "@global[0]", dns_key, new_dns_mode)
|
||||
uci:set(c_config, "@global[0]", "v2ray_dns_mode", "tcp")
|
||||
end
|
||||
end
|
||||
end
|
||||
api.uci_save(uci, appname, true, true)
|
||||
api.uci_save(uci, c_config, true, true)
|
||||
http.redirect(api.url("log"))
|
||||
end
|
||||
|
||||
function copy_node()
|
||||
local section = http.formvalue("section")
|
||||
local uid = api.gen_random_char()
|
||||
uci:section(appname, "nodes", uid)
|
||||
for k, v in pairs(uci:get_all(appname, section)) do
|
||||
uci:section(c_config, "nodes", uid)
|
||||
for k, v in pairs(uci:get_all(c_config, section)) do
|
||||
if not k:match("^%.") and k ~= "group" then
|
||||
if k == "remarks" then v = (v or "") .. "(1)" end
|
||||
uci:set(appname, uid, k, v)
|
||||
uci:set(c_config, uid, k, v)
|
||||
end
|
||||
end
|
||||
uci:set(appname, uid, "add_mode", 1)
|
||||
api.uci_save(uci, appname)
|
||||
uci:set(c_config, uid, "add_mode", 1)
|
||||
api.uci_save(uci, c_config)
|
||||
http.redirect(api.url("node_config", uid))
|
||||
end
|
||||
|
||||
function clear_all_nodes()
|
||||
uci:set(appname, '@global[0]', "enabled", "0")
|
||||
uci:set(appname, '@global[0]', "socks_enabled", "0")
|
||||
uci:set(appname, '@global_haproxy[0]', "balancing_enable", "0")
|
||||
uci:delete(appname, '@global[0]', "tcp_node")
|
||||
uci:delete(appname, '@global[0]', "udp_node")
|
||||
uci:foreach(appname, "socks", function(t)
|
||||
uci:delete(appname, t[".name"])
|
||||
uci:set_list(appname, t[".name"], "autoswitch_backup_node", {})
|
||||
uci:set(c_config, '@global[0]', "enabled", "0")
|
||||
uci:set(c_config, '@global[0]', "socks_enabled", "0")
|
||||
uci:set(c_config, '@global_haproxy[0]', "balancing_enable", "0")
|
||||
uci:delete(c_config, '@global[0]', "tcp_node")
|
||||
uci:delete(c_config, '@global[0]', "udp_node")
|
||||
uci:foreach(c_config, "socks", function(t)
|
||||
uci:delete(c_config, t[".name"])
|
||||
uci:set_list(c_config, t[".name"], "autoswitch_backup_node", {})
|
||||
end)
|
||||
uci:foreach(appname, "haproxy_config", function(t)
|
||||
uci:delete(appname, t[".name"])
|
||||
uci:foreach(c_config, "haproxy_config", function(t)
|
||||
uci:delete(c_config, t[".name"])
|
||||
end)
|
||||
uci:foreach(appname, "acl_rule", function(t)
|
||||
uci:delete(appname, t[".name"], "tcp_node")
|
||||
uci:delete(appname, t[".name"], "udp_node")
|
||||
uci:delete(c_config, t[".name"], "tcp_node")
|
||||
uci:delete(c_config, t[".name"], "udp_node")
|
||||
end)
|
||||
uci:foreach(appname, "nodes", function(node)
|
||||
uci:delete(appname, node['.name'])
|
||||
uci:foreach(c_config, "nodes", function(node)
|
||||
uci:delete(c_config, node['.name'])
|
||||
end)
|
||||
uci:foreach(appname, "subscribe_list", function(t)
|
||||
uci:delete(appname, t[".name"], "md5")
|
||||
uci:delete(appname, t[".name"], "chain_proxy")
|
||||
uci:delete(appname, t[".name"], "preproxy_node")
|
||||
uci:delete(appname, t[".name"], "to_node")
|
||||
uci:foreach(c_config, "subscribe_list", function(t)
|
||||
uci:delete(c_config, t[".name"], "md5")
|
||||
uci:delete(c_config, t[".name"], "chain_proxy")
|
||||
uci:delete(c_config, t[".name"], "preproxy_node")
|
||||
uci:delete(c_config, t[".name"], "to_node")
|
||||
end)
|
||||
|
||||
api.uci_save(uci, appname, true, true)
|
||||
api.uci_save(uci, c_config, true, true)
|
||||
end
|
||||
|
||||
function delete_select_nodes()
|
||||
local ids = http.formvalue("ids")
|
||||
local redirect = http.formvalue("redirect")
|
||||
string.gsub(ids, '[^' .. "," .. ']+', function(w)
|
||||
local socks
|
||||
uci:foreach(appname, "socks", function(t)
|
||||
uci:foreach(c_config, "socks", function(t)
|
||||
if t["node"] == w then
|
||||
uci:delete(appname, t[".name"])
|
||||
socks = "Socks_" .. t[".name"]
|
||||
uci:delete(c_config, t[".name"])
|
||||
end
|
||||
local changed = false
|
||||
local auto_switch_node_list = uci:get(appname, t[".name"], "autoswitch_backup_node") or {}
|
||||
local auto_switch_node_list = uci:get(c_config, t[".name"], "autoswitch_backup_node") or {}
|
||||
for i = #auto_switch_node_list, 1, -1 do
|
||||
if w == auto_switch_node_list[i] then
|
||||
table.remove(auto_switch_node_list, i)
|
||||
@@ -599,42 +601,40 @@ function delete_select_nodes()
|
||||
end
|
||||
end
|
||||
if changed then
|
||||
uci:set_list(appname, t[".name"], "autoswitch_backup_node", auto_switch_node_list)
|
||||
uci:set_list(c_config, t[".name"], "autoswitch_backup_node", auto_switch_node_list)
|
||||
end
|
||||
end)
|
||||
local tcp_node = uci:get(appname, "@global[0]", "tcp_node") or ""
|
||||
if tcp_node == w or tcp_node == socks then
|
||||
uci:delete(appname, '@global[0]', "tcp_node")
|
||||
if (uci:get(c_config, "@global[0]", "tcp_node") or "") == w then
|
||||
uci:delete(c_config, '@global[0]', "tcp_node")
|
||||
end
|
||||
local udp_node = uci:get(appname, "@global[0]", "udp_node") or ""
|
||||
if udp_node == w or udp_node == socks then
|
||||
uci:delete(appname, '@global[0]', "udp_node")
|
||||
if (uci:get(c_config, "@global[0]", "udp_node") or "") == w then
|
||||
uci:delete(c_config, '@global[0]', "udp_node")
|
||||
end
|
||||
uci:foreach(appname, "haproxy_config", function(t)
|
||||
uci:foreach(c_config, "haproxy_config", function(t)
|
||||
if t["lbss"] == w then
|
||||
uci:delete(appname, t[".name"])
|
||||
uci:delete(c_config, t[".name"])
|
||||
end
|
||||
end)
|
||||
uci:foreach(appname, "acl_rule", function(t)
|
||||
if t["tcp_node"] == w or t["tcp_node"] == socks then
|
||||
uci:delete(appname, t[".name"], "tcp_node")
|
||||
uci:foreach(c_config, "acl_rule", function(t)
|
||||
if t["tcp_node"] == w then
|
||||
uci:delete(c_config, t[".name"], "tcp_node")
|
||||
end
|
||||
if t["udp_node"] == w or t["udp_node"] == socks then
|
||||
uci:delete(appname, t[".name"], "udp_node")
|
||||
if t["udp_node"] == w then
|
||||
uci:delete(c_config, t[".name"], "udp_node")
|
||||
end
|
||||
end)
|
||||
uci:foreach(appname, "nodes", function(t)
|
||||
uci:foreach(c_config, "nodes", function(t)
|
||||
if t["preproxy_node"] == w then
|
||||
uci:delete(appname, t[".name"], "preproxy_node")
|
||||
uci:delete(appname, t[".name"], "chain_proxy")
|
||||
uci:delete(c_config, t[".name"], "preproxy_node")
|
||||
uci:delete(c_config, t[".name"], "chain_proxy")
|
||||
end
|
||||
if t["to_node"] == w then
|
||||
uci:delete(appname, t[".name"], "to_node")
|
||||
uci:delete(appname, t[".name"], "chain_proxy")
|
||||
uci:delete(c_config, t[".name"], "to_node")
|
||||
uci:delete(c_config, t[".name"], "chain_proxy")
|
||||
end
|
||||
local list_name = t["urltest_node"] and "urltest_node" or (t["balancing_node"] and "balancing_node")
|
||||
if list_name then
|
||||
local nodes = uci:get_list(appname, t[".name"], list_name)
|
||||
local nodes = uci:get_list(c_config, t[".name"], list_name)
|
||||
if nodes then
|
||||
local changed = false
|
||||
local new_nodes = {}
|
||||
@@ -646,48 +646,48 @@ function delete_select_nodes()
|
||||
end
|
||||
end
|
||||
if changed then
|
||||
uci:set_list(appname, t[".name"], list_name, new_nodes)
|
||||
uci:set_list(c_config, t[".name"], list_name, new_nodes)
|
||||
end
|
||||
end
|
||||
end
|
||||
if t["fallback_node"] == w or t["fallback_node"] == socks then
|
||||
uci:delete(appname, t[".name"], "fallback_node")
|
||||
if t["fallback_node"] == w then
|
||||
uci:delete(c_config, t[".name"], "fallback_node")
|
||||
end
|
||||
end)
|
||||
uci:foreach(appname, "subscribe_list", function(t)
|
||||
uci:foreach(c_config, "subscribe_list", function(t)
|
||||
if t["preproxy_node"] == w then
|
||||
uci:delete(appname, t[".name"], "preproxy_node")
|
||||
uci:delete(appname, t[".name"], "chain_proxy")
|
||||
uci:delete(c_config, t[".name"], "preproxy_node")
|
||||
uci:delete(c_config, t[".name"], "chain_proxy")
|
||||
end
|
||||
if t["to_node"] == w then
|
||||
uci:delete(appname, t[".name"], "to_node")
|
||||
uci:delete(appname, t[".name"], "chain_proxy")
|
||||
uci:delete(c_config, t[".name"], "to_node")
|
||||
uci:delete(c_config, t[".name"], "chain_proxy")
|
||||
end
|
||||
end)
|
||||
if (uci:get(appname, w, "add_mode") or "0") == "2" then
|
||||
local group = uci:get(appname, w, "group") or ""
|
||||
if (uci:get(c_config, w, "add_mode") or "0") == "2" then
|
||||
local group = uci:get(c_config, w, "group") or ""
|
||||
if group ~= "" then
|
||||
uci:foreach(appname, "subscribe_list", function(t)
|
||||
uci:foreach(c_config, "subscribe_list", function(t)
|
||||
if t["remark"] == group then
|
||||
uci:delete(appname, t[".name"], "md5")
|
||||
uci:delete(c_config, t[".name"], "md5")
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
uci:delete(appname, w)
|
||||
uci:delete(c_config, w)
|
||||
end)
|
||||
if redirect == "1" then
|
||||
api.uci_save(uci, appname)
|
||||
api.uci_save(uci, c_config)
|
||||
http.redirect(api.url("node_list"))
|
||||
else
|
||||
api.uci_save(uci, appname, true, true)
|
||||
api.uci_save(uci, c_config, true, true)
|
||||
end
|
||||
end
|
||||
|
||||
function get_node()
|
||||
local id = http.formvalue("id")
|
||||
local result = {}
|
||||
local show_node_info = api.uci_get_type("global_other", "show_node_info", "0")
|
||||
local show_node_info = uci:get(c_config, "@global_other[0]", "show_node_info") or "0"
|
||||
|
||||
local function add_is_ipv6_key(o)
|
||||
if o and o.address and show_node_info == "1" then
|
||||
@@ -700,12 +700,12 @@ function get_node()
|
||||
end
|
||||
|
||||
if id then
|
||||
result = uci:get_all(appname, id)
|
||||
result = uci:get_all(c_config, id)
|
||||
add_is_ipv6_key(result)
|
||||
else
|
||||
local default_nodes = {}
|
||||
local other_nodes = {}
|
||||
uci:foreach(appname, "nodes", function(t)
|
||||
uci:foreach(c_config, "nodes", function(t)
|
||||
add_is_ipv6_key(t)
|
||||
if not t.group or t.group == "" then
|
||||
default_nodes[#default_nodes + 1] = t
|
||||
@@ -724,12 +724,12 @@ function reassign_group()
|
||||
local group = http.formvalue("group") or "default"
|
||||
for id in ids:gmatch("([^,]+)") do
|
||||
if group ~="" and group ~= "default" then
|
||||
api.sh_uci_set(appname, id, "group", group)
|
||||
api.sh_uci_set(c_config, id, "group", group)
|
||||
else
|
||||
api.sh_uci_del(appname, id, "group")
|
||||
api.sh_uci_del(c_config, id, "group")
|
||||
end
|
||||
end
|
||||
api.sh_uci_commit(appname)
|
||||
api.sh_uci_commit(c_config)
|
||||
http_write_json({ status = "ok" })
|
||||
end
|
||||
|
||||
@@ -737,7 +737,7 @@ function save_node_list_opt()
|
||||
local option = http.formvalue("option") or ""
|
||||
local value = http.formvalue("value") or ""
|
||||
if option ~= "" then
|
||||
api.sh_uci_set(appname, "@global_other[0]", option, value, true)
|
||||
api.sh_uci_set(c_config, "@global_other[0]", option, value, true)
|
||||
end
|
||||
http_write_json({ status = "ok" })
|
||||
end
|
||||
@@ -760,8 +760,8 @@ function rollback_rules()
|
||||
return
|
||||
end
|
||||
local bak_dir = "/tmp/bak_v2ray/"
|
||||
local geo_dir = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/")
|
||||
local geo2rule = uci:get(appname, "@global_rules[0]", "geo2rule") or "0"
|
||||
local geo_dir = (uci:get(c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/")
|
||||
local geo2rule = uci:get(c_config, "@global_rules[0]", "geo2rule") or "0"
|
||||
fs.move(bak_dir .. arg_type .. ".dat", geo_dir .. arg_type .. ".dat")
|
||||
fs.rmdir(bak_dir)
|
||||
if geo2rule == "1" and rules ~= "" then
|
||||
@@ -777,9 +777,9 @@ function server_update_config()
|
||||
local data_t = jsonParse(data) or {}
|
||||
if next(data_t) then
|
||||
for k, v in pairs(data_t) do
|
||||
uci:set(appname .. "_server", id, k, v)
|
||||
uci:set(c_config .. "_server", id, k, v)
|
||||
end
|
||||
api.uci_save(uci, appname .. "_server")
|
||||
api.uci_save(uci, c_config .. "_server")
|
||||
http_write_json_ok()
|
||||
return
|
||||
end
|
||||
@@ -914,7 +914,7 @@ function restore_backup()
|
||||
fp:write(decoded)
|
||||
fp:close()
|
||||
if chunk_index + 1 == total_chunks then
|
||||
uci:revert(appname)
|
||||
uci:revert(c_config)
|
||||
luci.sys.call("echo '' > /tmp/log/passwall.log")
|
||||
api.log(" * PassWall 配置文件上传成功…")
|
||||
local temp_dir = '/tmp/passwall_bak'
|
||||
@@ -957,7 +957,7 @@ function geo_view()
|
||||
end
|
||||
local function get_rules(str, type)
|
||||
local rules_id = {}
|
||||
uci:foreach(appname, "shunt_rules", function(s)
|
||||
uci:foreach(c_config, "shunt_rules", function(s)
|
||||
local list
|
||||
if type == "geoip" then list = s.ip_list else list = s.domain_list end
|
||||
for line in string.gmatch((list or ""), "[^\r\n]+") do
|
||||
@@ -974,7 +974,7 @@ function geo_view()
|
||||
end)
|
||||
return rules_id
|
||||
end
|
||||
local geo_dir = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/")
|
||||
local geo_dir = (uci:get(c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/")
|
||||
local geosite_path = geo_dir .. "/geosite.dat"
|
||||
local geoip_path = geo_dir .. "/geoip.dat"
|
||||
local geo_type, file_path, cmd
|
||||
@@ -1046,13 +1046,13 @@ function subscribe_manual()
|
||||
http_write_json({ success = false, msg = "Missing section or URL, skip." })
|
||||
return
|
||||
end
|
||||
local uci_url = api.sh_uci_get(appname, section, "url")
|
||||
local uci_url = api.sh_uci_get(c_config, section, "url")
|
||||
if not uci_url or uci_url == "" then
|
||||
http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") })
|
||||
return
|
||||
end
|
||||
if uci_url ~= current_url then
|
||||
api.sh_uci_set(appname, section, "url", current_url, true)
|
||||
api.sh_uci_set(c_config, section, "url", current_url, true)
|
||||
end
|
||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. section .. " manual >/dev/null 2>&1 &")
|
||||
http_write_json({ success = true, msg = "Subscribe triggered." })
|
||||
@@ -1069,7 +1069,7 @@ function subscribe_manual_all()
|
||||
local url_list = util.split(urls, ",")
|
||||
-- 检查是否存在未保存配置
|
||||
for i, section in ipairs(section_list) do
|
||||
local uci_url = api.sh_uci_get(appname, section, "url")
|
||||
local uci_url = api.sh_uci_get(c_config, section, "url")
|
||||
if not uci_url or uci_url == "" then
|
||||
http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") })
|
||||
return
|
||||
@@ -1078,9 +1078,9 @@ function subscribe_manual_all()
|
||||
-- 保存有变动的url
|
||||
for i, section in ipairs(section_list) do
|
||||
local current_url = url_list[i] or ""
|
||||
local uci_url = api.sh_uci_get(appname, section, "url")
|
||||
local uci_url = api.sh_uci_get(c_config, section, "url")
|
||||
if current_url ~= "" and uci_url ~= current_url then
|
||||
api.sh_uci_set(appname, section, "url", current_url, true)
|
||||
api.sh_uci_set(c_config, section, "url", current_url, true)
|
||||
end
|
||||
end
|
||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start all manual >/dev/null 2>&1 &")
|
||||
@@ -1091,10 +1091,10 @@ function flush_set()
|
||||
local redirect = http.formvalue("redirect") or "0"
|
||||
local reload = http.formvalue("reload") or "0"
|
||||
if reload == "1" then
|
||||
uci:set(appname, '@global[0]', "flush_set", "1")
|
||||
api.uci_save(uci, appname, true, true)
|
||||
uci:set(c_config, '@global[0]', "flush_set", "1")
|
||||
api.uci_save(uci, c_config, true, true)
|
||||
else
|
||||
api.sh_uci_set(appname, "@global[0]", "flush_set", "1", true)
|
||||
api.sh_uci_set(c_config, "@global[0]", "flush_set", "1", true)
|
||||
end
|
||||
if redirect == "1" then
|
||||
http.redirect(api.url("log"))
|
||||
@@ -1103,9 +1103,9 @@ end
|
||||
|
||||
function fetch_certsha256()
|
||||
local id = http.formvalue("id") or ""
|
||||
local address = (id ~= "") and uci:get(appname, id, "address") or ""
|
||||
local port = (id ~= "") and uci:get(appname, id, "port") or 0
|
||||
local sni = (id ~= "") and uci:get(appname, id, "tls_serverName") or ""
|
||||
local address = (id ~= "") and uci:get(c_config, id, "address") or ""
|
||||
local port = (id ~= "") and uci:get(c_config, id, "port") or 0
|
||||
local sni = (id ~= "") and uci:get(c_config, id, "tls_serverName") or ""
|
||||
sni = (sni ~= "") and sni or address
|
||||
local protocol = uci:get(appname, id, "protocol")
|
||||
local h3, timeout = false, 10
|
||||
@@ -1130,11 +1130,11 @@ function get_shunt_rules()
|
||||
local result = {}
|
||||
|
||||
if id then
|
||||
result = uci:get_all(appname, id)
|
||||
result = uci:get_all(c_config, id)
|
||||
else
|
||||
local default_items = {}
|
||||
local other_items = {}
|
||||
uci:foreach(appname, "shunt_rules", function(t)
|
||||
uci:foreach(c_config, "shunt_rules", function(t)
|
||||
if not t.group or t.group == "" then
|
||||
default_items[#default_items + 1] = t
|
||||
else
|
||||
@@ -1153,7 +1153,7 @@ function add_shunt_rule()
|
||||
|
||||
local uid = add_name
|
||||
if add_name then
|
||||
local has = uci:get(appname, uid)
|
||||
local has = uci:get(c_config, uid)
|
||||
if has then
|
||||
http_write_json_error({ message = i18n.translate("This ID already exists.") })
|
||||
return
|
||||
@@ -1161,18 +1161,18 @@ function add_shunt_rule()
|
||||
else
|
||||
uid = api.gen_random_char()
|
||||
end
|
||||
uci:section(appname, "shunt_rules", uid)
|
||||
uci:section(c_config, "shunt_rules", uid)
|
||||
|
||||
local group = http.formvalue("group")
|
||||
if group and group ~= "default" then
|
||||
uci:set(appname, uid, "group", group)
|
||||
uci:set(c_config, uid, "group", group)
|
||||
end
|
||||
|
||||
if redirect == "1" then
|
||||
api.uci_save(uci, appname)
|
||||
api.uci_save(uci, c_config)
|
||||
http.redirect(api.url("shunt_rules", uid))
|
||||
else
|
||||
api.uci_save(uci, appname)
|
||||
api.uci_save(uci, c_config)
|
||||
http_write_json_ok({uid = uid, redirect_url = api.url("shunt_rules", uid)})
|
||||
end
|
||||
end
|
||||
@@ -1181,17 +1181,17 @@ function delete_select_shunt_rules()
|
||||
local ids = http.formvalue("ids")
|
||||
local redirect = http.formvalue("redirect")
|
||||
string.gsub(ids, '[^' .. "," .. ']+', function(w)
|
||||
uci:foreach(appname, "nodes", function(s)
|
||||
uci:foreach(c_config, "nodes", function(s)
|
||||
if s["protocol"] and s["protocol"] == "_shunt" then
|
||||
uci:delete(appname, s[".name"], w)
|
||||
uci:delete(c_config, s[".name"], w)
|
||||
end
|
||||
end)
|
||||
uci:delete(appname, w)
|
||||
uci:delete(c_config, w)
|
||||
end)
|
||||
if redirect == "1" then
|
||||
api.uci_save(uci, appname)
|
||||
api.uci_save(uci, c_config)
|
||||
http.redirect(api.url("rule"))
|
||||
else
|
||||
api.uci_save(uci, appname, true, true)
|
||||
api.uci_save(uci, c_config, true, true)
|
||||
end
|
||||
end
|
||||
@@ -1,22 +1,17 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = "passwall"
|
||||
local sys = api.sys
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
s = m:section(TypedSection, "global", translate("ACLs"), "<font color='red'>" .. translate("ACLs is a tools which used to designate specific IP proxy mode.") .. "</font>")
|
||||
s.anonymous = true
|
||||
s = m:section(NamedSection, "@global[0]", "global", translate("ACLs"), "<font color='red'>" .. translate("ACLs is a tools which used to designate specific IP proxy mode.") .. "</font>")
|
||||
|
||||
o = s:option(Flag, "acl_enable", translate("Main switch"))
|
||||
o.rmempty = false
|
||||
o.default = false
|
||||
|
||||
-- [[ ACLs Settings ]]--
|
||||
local cfgname = "acl_rule"
|
||||
s = m:section(TypedSection, cfgname)
|
||||
s = m:section(TypedSection, "acl_rule")
|
||||
s.template = "cbi/tblsection"
|
||||
s.sortable = true
|
||||
s.anonymous = true
|
||||
@@ -28,7 +23,7 @@ function s.create(e, t)
|
||||
luci.http.redirect(e.extedit:format(uid))
|
||||
end
|
||||
function s.remove(e, t)
|
||||
sys.call("rm -rf /tmp/etc/passwall_tmp/dns_" .. t .. "*")
|
||||
api.sys.call("rm -rf /tmp/etc/passwall_tmp/dns_" .. t .. "*")
|
||||
TypedSection.remove(e, t)
|
||||
end
|
||||
|
||||
@@ -42,7 +37,7 @@ o = s:option(Value, "remarks", translate("Remarks"))
|
||||
o.rmempty = true
|
||||
|
||||
local mac_t = {}
|
||||
sys.net.mac_hints(function(e, t)
|
||||
api.sys.net.mac_hints(function(e, t)
|
||||
mac_t[e] = {
|
||||
ip = t,
|
||||
mac = e
|
||||
@@ -85,41 +80,6 @@ i.cfgvalue = function(t, n)
|
||||
return translate("No Proxy")
|
||||
end
|
||||
|
||||
--[[
|
||||
---- TCP No Redir Ports
|
||||
o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports"))
|
||||
o.default = "default"
|
||||
o:value("disable", translate("No patterns are used"))
|
||||
o:value("default", translate("Default"))
|
||||
o:value("1:65535", translate("All"))
|
||||
|
||||
---- UDP No Redir Ports
|
||||
o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"))
|
||||
o.default = "default"
|
||||
o:value("disable", translate("No patterns are used"))
|
||||
o:value("default", translate("Default"))
|
||||
o:value("1:65535", translate("All"))
|
||||
|
||||
---- TCP Redir Ports
|
||||
o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports"))
|
||||
o.default = "default"
|
||||
o:value("default", translate("Default"))
|
||||
o:value("1:65535", translate("All"))
|
||||
o:value("80,443", "80,443")
|
||||
o:value("80:65535", "80 " .. translate("or more"))
|
||||
o:value("1:443", "443 " .. translate("or less"))
|
||||
|
||||
---- UDP Redir Ports
|
||||
o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports"))
|
||||
o.default = "default"
|
||||
o:value("default", translate("Default"))
|
||||
o:value("1:65535", translate("All"))
|
||||
o:value("53", "53")
|
||||
]]--
|
||||
|
||||
local sortable = Template(appname .. "/cbi/sortable")
|
||||
sortable.api = api
|
||||
sortable.target_cfgname = cfgname
|
||||
m:append(sortable)
|
||||
m:appendTemplate("/cbi/sortable", {sectiontype = s.sectiontype})
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -1,26 +1,20 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = "passwall"
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
m = Map()
|
||||
m.redirect = api.url("acl")
|
||||
api.set_apply_on_parse(m)
|
||||
|
||||
local cfgid = arg[1]
|
||||
if not cfgid or not m:get(cfgid) then
|
||||
if not arg[1] or not m:get(arg[1]) then
|
||||
luci.http.redirect(m.redirect)
|
||||
end
|
||||
|
||||
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
|
||||
m:appendTemplate("/cbi/nodes_listvalue_com")
|
||||
|
||||
local fs = api.fs
|
||||
local sys = api.sys
|
||||
local has_singbox = api.finded_com("sing-box")
|
||||
local has_xray = api.finded_com("xray")
|
||||
local has_gfwlist = fs.access("/usr/share/passwall/rules/gfwlist")
|
||||
local has_chnlist = fs.access("/usr/share/passwall/rules/chnlist")
|
||||
local has_chnroute = fs.access("/usr/share/passwall/rules/chnroute")
|
||||
local has_gfwlist = api.fs.access("/usr/share/passwall/rules/gfwlist")
|
||||
local has_chnlist = api.fs.access("/usr/share/passwall/rules/chnlist")
|
||||
local has_chnroute = api.fs.access("/usr/share/passwall/rules/chnroute")
|
||||
|
||||
local port_validate = function(self, value, t)
|
||||
return value:gsub("-", ":")
|
||||
@@ -39,10 +33,10 @@ for _, v in pairs(nodes_table) do
|
||||
end
|
||||
|
||||
local socks_list = {}
|
||||
m.uci:foreach(appname, "socks", function(s)
|
||||
m:foreach("socks", function(s)
|
||||
if s.enabled == "1" and s.node then
|
||||
socks_list[#socks_list + 1] = {
|
||||
id = "Socks_" .. s[".name"],
|
||||
id = s[".name"],
|
||||
remark = translate("Socks Config") .. " " .. string.format("[%s %s]", s.port, translate("Port")),
|
||||
group = "Socks"
|
||||
}
|
||||
@@ -50,7 +44,7 @@ m.uci:foreach(appname, "socks", function(s)
|
||||
end)
|
||||
|
||||
-- [[ ACLs Settings ]]--
|
||||
s = m:section(NamedSection, cfgid, translate("ACLs"), translate("ACLs"))
|
||||
s = m:section(NamedSection, arg[1], translate("ACLs"), translate("ACLs"))
|
||||
s.addremove = false
|
||||
s.dynamic = false
|
||||
|
||||
@@ -61,7 +55,7 @@ o.rmempty = false
|
||||
|
||||
---- Remarks
|
||||
o = s:option(Value, "remarks", translate("Remarks"))
|
||||
o.default = cfgid
|
||||
o.default = arg[1]
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "interface", translate("Source Interface"))
|
||||
@@ -78,7 +72,7 @@ o.validate = function(self, value, section)
|
||||
end
|
||||
|
||||
local mac_t = {}
|
||||
sys.net.mac_hints(function(e, t)
|
||||
api.sys.net.mac_hints(function(e, t)
|
||||
mac_t[#mac_t + 1] = {
|
||||
ip = t,
|
||||
mac = e
|
||||
@@ -188,7 +182,7 @@ o:depends("mode", "1")
|
||||
o.validate = port_validate
|
||||
|
||||
o = s:option(DummyValue, "_hide_node_option", "")
|
||||
o.template = "passwall/cbi/hidevalue"
|
||||
o.template = m:template_path("/cbi/hidevalue")
|
||||
o.value = "1"
|
||||
o:depends("mode", "0")
|
||||
o:depends({ tcp_no_redir_ports = "1:65535", udp_no_redir_ports = "1:65535" })
|
||||
@@ -204,7 +198,7 @@ o:depends({ _hide_node_option = "1", ['!reverse'] = true })
|
||||
o = s:option(ListValue, "tcp_node", "<a style='color: red'>" .. translate("TCP Node") .. "</a>")
|
||||
o.default = ""
|
||||
o:depends({ _hide_node_option = false, use_global_config = false })
|
||||
o.template = appname .. "/cbi/nodes_listvalue"
|
||||
o.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o.group = {}
|
||||
o.remove = function(self, section)
|
||||
m:del(section, self.option)
|
||||
@@ -212,7 +206,7 @@ o.remove = function(self, section)
|
||||
end
|
||||
|
||||
o = s:option(DummyValue, "_tcp_node_bool", "")
|
||||
o.template = "passwall/cbi/hidevalue"
|
||||
o.template = m:template_path("/cbi/hidevalue")
|
||||
o.value = "1"
|
||||
o:depends({ tcp_node = "", ['!reverse'] = true })
|
||||
|
||||
@@ -221,7 +215,7 @@ o.default = ""
|
||||
o:value("", translate("Close"))
|
||||
o:value("tcp", translate("Same as the tcp node"))
|
||||
o:depends({ _tcp_node_bool = "1", _node_sel_other = "1" })
|
||||
o.template = appname .. "/cbi/nodes_listvalue"
|
||||
o.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o.group = {"",""}
|
||||
o.remove = function(self, section)
|
||||
local v = s.fields["shunt_udp_node"]:formvalue(section)
|
||||
@@ -248,7 +242,7 @@ o.write = function(self, section, value)
|
||||
end
|
||||
|
||||
o = s:option(DummyValue, "_udp_node_bool", "")
|
||||
o.template = "passwall/cbi/hidevalue"
|
||||
o.template = m:template_path("/cbi/hidevalue")
|
||||
o.value = "1"
|
||||
o:depends({ udp_node = "", ['!reverse'] = true })
|
||||
o:depends({ shunt_udp_node = "tcp" })
|
||||
@@ -355,17 +349,17 @@ o:value("proxy", translate("Proxy"))
|
||||
o:depends({ _udp_node_bool = "1" })
|
||||
|
||||
o = s:option(DummyValue, "switch_mode", " ")
|
||||
o.template = appname .. "/global/proxy"
|
||||
o.template = m:template_path("/global/proxy")
|
||||
o:depends({ _tcp_node_bool = "1" })
|
||||
|
||||
-- Node → DNS Depends Settings
|
||||
o = s:option(DummyValue, "_node_sel_shunt", "")
|
||||
o.template = appname .. "/cbi/hidevalue"
|
||||
o.template = m:template_path("/cbi/hidevalue")
|
||||
o.value = "1"
|
||||
o:depends({ tcp_node = "__always__" })
|
||||
|
||||
o = s:option(DummyValue, "_node_sel_other", "")
|
||||
o.template = appname .. "/cbi/hidevalue"
|
||||
o.template = m:template_path("/cbi/hidevalue")
|
||||
o.value = "1"
|
||||
o:depends({ _node_sel_shunt = "1", ['!reverse'] = true })
|
||||
|
||||
@@ -603,9 +597,6 @@ for k, v in pairs(nodes_table) do
|
||||
end
|
||||
end
|
||||
|
||||
local footer = Template(appname .. "/acl/config_footer")
|
||||
footer.api = api
|
||||
footer.cfgid = cfgid
|
||||
m:append(footer)
|
||||
m:appendTemplate("/acl/config_footer", {section = arg[1]})
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -1,21 +1,15 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local com = require "luci.passwall.com"
|
||||
local appname = "passwall"
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
local com = require "luci.passwall.com"
|
||||
|
||||
m = Map()
|
||||
|
||||
-- [[ App Settings ]]--
|
||||
s = m:section(TypedSection, "global_app", translate("App Update"))
|
||||
s.anonymous = true
|
||||
s = m:section(NamedSection, "@global_app[0]", "global_app", translate("App Update"))
|
||||
|
||||
local app_version = Template(appname .. "/app_update/app_version")
|
||||
app_version.api = api
|
||||
app_version.config = m.config
|
||||
app_version.com = com
|
||||
s:append(app_version)
|
||||
s:appendTemplate("/app_update/app_version", {com = com})
|
||||
|
||||
o = s:option(Flag, "github_proxy", translate("GitHub Proxy"), translate("Use gh-proxy instead of proxy nodes for component updates."))
|
||||
o.default = 0
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
api = require "luci.passwall.api"
|
||||
appname = "passwall"
|
||||
datatypes = api.datatypes
|
||||
local fs = api.fs
|
||||
has_singbox = api.finded_com("sing-box")
|
||||
@@ -10,10 +9,9 @@ local has_chnroute = fs.access("/usr/share/passwall/rules/chnroute")
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
|
||||
m:appendTemplate("/cbi/nodes_listvalue_com")
|
||||
|
||||
local nodes_table = {}
|
||||
for _, e in ipairs(api.get_valid_nodes()) do
|
||||
@@ -51,7 +49,7 @@ socks_table[#socks_table + 1] = {
|
||||
id = tcp_socks_server,
|
||||
remark = tcp_socks_server .. " - " .. translate("TCP Node")
|
||||
}
|
||||
m.uci:foreach(appname, "socks", function(s)
|
||||
m:foreach("socks", function(s)
|
||||
if s.enabled == "1" and s.node then
|
||||
local id, remark
|
||||
for k, n in pairs(nodes_table) do
|
||||
@@ -95,13 +93,9 @@ local doh_validate = function(self, value, t)
|
||||
return nil, translatef("%s request address","DoH") .. " " .. translate("Format must be:") .. " URL,IP"
|
||||
end
|
||||
|
||||
m:append(Template(appname .. "/global/status"))
|
||||
m:appendTemplate("/global/status")
|
||||
|
||||
global_cfgid = (m:get("@global[0]") or {})[".name"] or ""
|
||||
|
||||
s = m:section(TypedSection, "global")
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
s = m:section(NamedSection, "@global[0]", "global")
|
||||
|
||||
s:tab("Main", translate("Main"))
|
||||
|
||||
@@ -111,13 +105,13 @@ o.rmempty = false
|
||||
|
||||
---- TCP Node
|
||||
o = s:taboption("Main", ListValue, "tcp_node", "<a style='color: red'>" .. translate("TCP Node") .. "</a>")
|
||||
o.template = appname .. "/cbi/nodes_listvalue"
|
||||
o.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o:value("", translate("Close"))
|
||||
o.group = {""}
|
||||
|
||||
---- UDP Node
|
||||
o = s:taboption("Main", ListValue, "udp_node", "<a style='color: red'>" .. translate("UDP Node") .. "</a>")
|
||||
o.template = appname .. "/cbi/nodes_listvalue"
|
||||
o.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o:value("", translate("Close"))
|
||||
o:value("tcp", translate("Same as the tcp node"))
|
||||
o.group = {"",""}
|
||||
@@ -146,15 +140,16 @@ o.write = function(self, section, value)
|
||||
return m:set(section, "udp_node", value)
|
||||
end
|
||||
|
||||
current_node_id = m:get(s.section, "tcp_node")
|
||||
current_node = current_node_id and m:get(current_node_id) or {}
|
||||
|
||||
-- Shunt Start
|
||||
if (has_singbox or has_xray) and #nodes_table > 0 then
|
||||
if #normal_list > 0 or #iface_list > 0 then
|
||||
current_node_id = m.uci:get(appname, global_cfgid, "tcp_node")
|
||||
current_node = current_node_id and m.uci:get_all(appname, current_node_id) or {}
|
||||
if current_node.protocol == "_shunt" then
|
||||
local shunt_lua = loadfile("/usr/lib/lua/luci/model/cbi/passwall/client/include/shunt_options.lua")
|
||||
setfenv(shunt_lua, getfenv(1))(m, s, {
|
||||
s_cfgid = s:cfgsections()[1],
|
||||
s_cfgid = s.section,
|
||||
node_id = current_node_id,
|
||||
node = current_node,
|
||||
socks_list = socks_list,
|
||||
@@ -200,12 +195,12 @@ o:depends({ tcp_node = "", ["!reverse"] = true })
|
||||
|
||||
-- Node → DNS Depends Settings
|
||||
o = s:taboption("Main", DummyValue, "_node_sel_shunt", "")
|
||||
o.template = appname .. "/cbi/hidevalue"
|
||||
o.template = m:template_path("/cbi/hidevalue")
|
||||
o.value = "1"
|
||||
o:depends({ tcp_node = "__always__" })
|
||||
|
||||
o = s:taboption("Main", DummyValue, "_node_sel_other", "")
|
||||
o.template = appname .. "/cbi/hidevalue"
|
||||
o.template = m:template_path("/cbi/hidevalue")
|
||||
o.value = "1"
|
||||
o:depends({ _node_sel_shunt = "1", ['!reverse'] = true })
|
||||
|
||||
@@ -583,7 +578,7 @@ o:value("proxy", translate("Proxy"))
|
||||
o.default = "proxy"
|
||||
|
||||
o = s:taboption("Proxy", DummyValue, "switch_mode", " ")
|
||||
o.template = appname .. "/global/proxy"
|
||||
o.template = m:template_path("/global/proxy")
|
||||
|
||||
---- Check the transparent proxy component
|
||||
local handle = io.popen("lsmod")
|
||||
@@ -662,11 +657,11 @@ end
|
||||
|
||||
s:tab("faq", "FAQ")
|
||||
o = s:taboption("faq", DummyValue, "")
|
||||
o.template = appname .. "/global/faq"
|
||||
o.template = m:template_path("/global/faq")
|
||||
|
||||
s:tab("maintain", translate("Maintain"))
|
||||
o = s:taboption("maintain", DummyValue, "")
|
||||
o.template = appname .. "/global/backup"
|
||||
o.template = m:template_path("/global/backup")
|
||||
|
||||
-- [[ Socks Server ]]--
|
||||
o = s:taboption("Main", Flag, "socks_enabled", "Socks " .. translate("Main switch"))
|
||||
@@ -683,27 +678,26 @@ function s2.create(e, t)
|
||||
luci.http.redirect(e.extedit:format(uid))
|
||||
end
|
||||
function s2.remove(e, t)
|
||||
local socks = "Socks_" .. 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 "") == socks then
|
||||
if (m:get("@global[0]", "tcp_node") or "") == t then
|
||||
m:set('@global[0]', "tcp_node", new_node)
|
||||
end
|
||||
if (m:get("@global[0]", "udp_node") or "") == socks then
|
||||
if (m:get("@global[0]", "udp_node") or "") == t then
|
||||
m:set('@global[0]', "udp_node", new_node)
|
||||
end
|
||||
m.uci:foreach(appname, "acl_rule", function(s)
|
||||
if s["tcp_node"] and s["tcp_node"] == socks then
|
||||
m:foreach("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"] == socks then
|
||||
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)
|
||||
m:foreach("nodes", function(s)
|
||||
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)
|
||||
@@ -711,7 +705,7 @@ function s2.remove(e, t)
|
||||
local changed = false
|
||||
local new_nodes = {}
|
||||
for _, node in ipairs(nodes) do
|
||||
if node ~= socks then
|
||||
if node ~= t then
|
||||
table.insert(new_nodes, node)
|
||||
else
|
||||
changed = true
|
||||
@@ -722,7 +716,7 @@ function s2.remove(e, t)
|
||||
end
|
||||
end
|
||||
end
|
||||
if s["fallback_node"] == socks then
|
||||
if s["fallback_node"] == t then
|
||||
m:del(s[".name"], "fallback_node")
|
||||
end
|
||||
end)
|
||||
@@ -741,7 +735,7 @@ o.default = 1
|
||||
o.rmempty = false
|
||||
|
||||
o = s2:option(ListValue, "node", translate("Socks Node"))
|
||||
o.template = appname .. "/cbi/nodes_listvalue"
|
||||
o.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o.group = {}
|
||||
|
||||
o = s2:option(DummyValue, "now_node", translate("Current Node"))
|
||||
@@ -757,7 +751,7 @@ o.cfgvalue = function(_, n)
|
||||
end
|
||||
|
||||
local n = 1
|
||||
m.uci:foreach(appname, "socks", function(s)
|
||||
m:foreach("socks", function(s)
|
||||
if s[".name"] == section then
|
||||
return false
|
||||
end
|
||||
@@ -819,10 +813,6 @@ for k, v in pairs(nodes_table) do
|
||||
end
|
||||
end
|
||||
|
||||
local footer = Template(appname .. "/global/footer")
|
||||
footer.api = api
|
||||
footer.global_cfgid = global_cfgid
|
||||
footer.shunt_list = api.jsonc.stringify(shunt_list)
|
||||
m:append(footer)
|
||||
m:appendTemplate("/global/footer", {shunt_list = api.jsonc.stringify(shunt_list)})
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -1,7 +1,6 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = api.appname
|
||||
local datatypes = api.datatypes
|
||||
local net = require "luci.model.network".init()
|
||||
api.set_default_cbi()
|
||||
|
||||
local nodes_table = {}
|
||||
for k, e in ipairs(api.get_valid_nodes()) do
|
||||
@@ -15,18 +14,14 @@ for k, e in ipairs(api.get_valid_nodes()) do
|
||||
end
|
||||
end
|
||||
|
||||
api.set_default_cbi()
|
||||
m = Map(api.c_config, "HAPROXY " .. translate("Load Balancing"))
|
||||
|
||||
m = Map(appname, "HAPROXY " .. translate("Load Balancing"))
|
||||
api.set_apply_on_parse(m)
|
||||
|
||||
m:append(Template(appname .. "/cbi/nodes_value_com"))
|
||||
m:appendTemplate("/cbi/nodes_value_com")
|
||||
|
||||
-- [[ Haproxy Settings ]]--
|
||||
s = m:section(TypedSection, "global_haproxy", translate("Basic Settings"))
|
||||
s.anonymous = true
|
||||
s = m:section(NamedSection, "@global_haproxy[0]", "global_haproxy", translate("Basic Settings"))
|
||||
|
||||
s:append(Template(appname .. "/haproxy/status"))
|
||||
s:appendTemplate("/haproxy/status")
|
||||
|
||||
---- Balancing Enable
|
||||
o = s:option(Flag, "balancing_enable", translate("Enable Load Balancing"))
|
||||
@@ -69,9 +64,9 @@ o:depends("balancing_enable", true)
|
||||
|
||||
---- Health Check Type
|
||||
o = s:option(ListValue, "health_check_type", translate("Health Check Type"))
|
||||
o.default = "passwall_logic"
|
||||
o.default = "script_logic"
|
||||
o:value("tcp", "TCP")
|
||||
o:value("passwall_logic", translate("URL Test") .. string.format("(passwall %s)", translate("Inner implement")))
|
||||
o:value("script_logic", translate("URL Test") .. string.format("(passwall %s)", translate("Inner implement")))
|
||||
o:depends("balancing_enable", true)
|
||||
|
||||
---- Passwall Inner implement Probe URL
|
||||
@@ -85,7 +80,7 @@ o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud
|
||||
o:value("https://wifi.vivo.com.cn/generate_204", "VIVO (CN)")
|
||||
o.default = o.keylist[3]
|
||||
o.description = translate("The URL used to detect the connection status.")
|
||||
o:depends("health_check_type", "passwall_logic")
|
||||
o:depends("health_check_type", "script_logic")
|
||||
|
||||
---- Health Check Inter
|
||||
o = s:option(Value, "health_check_inter", translate("Health Check Inter"))
|
||||
@@ -100,11 +95,10 @@ o.rawhtml = true
|
||||
o.cfgvalue = function(t, n)
|
||||
return string.format('<span style="color: red">%s</span>', translate("When the URL test is used, the load balancing node will be converted into a Socks node. when node list set customizing, must be a Socks node, otherwise the health check will be invalid."))
|
||||
end
|
||||
o:depends("health_check_type", "passwall_logic")
|
||||
o:depends("health_check_type", "script_logic")
|
||||
|
||||
-- [[ Balancing Settings ]]--
|
||||
local cfgname = "haproxy_config"
|
||||
s = m:section(TypedSection, cfgname, translate("Node List"))
|
||||
s = m:section(TypedSection, "haproxy_config", translate("Node List"))
|
||||
s.description = "<font color='red'>" ..
|
||||
translate("Add a node, Export Of Multi WAN Only support Multi Wan. Load specific gravity range 1-256. Multiple primary servers can be load balanced, standby will only be enabled when the primary server is offline! Multiple groups can be set, Haproxy port same one for each group.") .. "<br>" ..
|
||||
translate("Note that the node configuration parameters for load balancing must be consistent when use TCP health check type, otherwise it cannot be used normally!") .. "</font>"
|
||||
@@ -133,7 +127,7 @@ o.rmempty = false
|
||||
|
||||
---- Node Address
|
||||
o = s:option(Value, "lbss", translate("Node Address"))
|
||||
o.template = appname .. "/cbi/nodes_value"
|
||||
o.template = m:template_path("/cbi/nodes_value")
|
||||
o.group = {}
|
||||
for k, v in pairs(nodes_table) do
|
||||
o:value(v.id, v.remarks)
|
||||
@@ -181,11 +175,8 @@ o:value(0, translate("Primary"))
|
||||
o:value(1, translate("Standby"))
|
||||
o.rmempty = false
|
||||
|
||||
local sortable = Template(appname .. "/cbi/sortable")
|
||||
sortable.api = api
|
||||
sortable.target_cfgname = cfgname
|
||||
m:append(sortable)
|
||||
m:appendTemplate("/cbi/sortable", {sectiontype = s.sectiontype})
|
||||
|
||||
m:append(Template(appname .. "/haproxy/js"))
|
||||
m:appendTemplate("/haproxy/js")
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -9,7 +9,7 @@ local current_node_id = data.node_id
|
||||
local node_list = data.node_list or api.get_node_list()
|
||||
|
||||
local groups = {}
|
||||
m.uci:foreach(appname, "shunt_rules", function(s)
|
||||
m:foreach("shunt_rules", function(s)
|
||||
if s.group and s.group ~= "" then
|
||||
groups[s.group] = true
|
||||
end
|
||||
@@ -109,7 +109,7 @@ end
|
||||
local shunt_group_val = m:get(current_node_id, "shunt_group") or ""
|
||||
shunt_group_val = shunt_group_val:lower()
|
||||
local shunt_rules = {}
|
||||
m.uci:foreach(appname, "shunt_rules", function(e)
|
||||
m:foreach("shunt_rules", function(e)
|
||||
local group = e.group or ""
|
||||
group = group:lower()
|
||||
if group == shunt_group_val then
|
||||
@@ -132,7 +132,7 @@ table.insert(shunt_rules, {
|
||||
})
|
||||
|
||||
s2 = m:section(Table, shunt_rules, " ")
|
||||
s2.config = appname
|
||||
s2.config = m.config
|
||||
s2.sectiontype = "shunt_option_list"
|
||||
|
||||
o = s2:option(DummyValue, "remarks", translate("Rule"))
|
||||
@@ -146,7 +146,7 @@ o.cfgvalue = function(self, section)
|
||||
end
|
||||
|
||||
_node = s2:option(Value, "_node", translate("Node"))
|
||||
_node.template = appname .. "/cbi/nodes_listvalue"
|
||||
_node.template = m:template_path("/cbi/nodes_listvalue")
|
||||
_node.group = {"","","",""}
|
||||
_node:value("", translate("Close (Not use)"))
|
||||
_node:value("_default", translate("Use default node"))
|
||||
@@ -178,7 +178,7 @@ end
|
||||
proxy_tag_node = s2:option(ListValue, "_proxy_tag", string.format('<a style="color:red" title="%s">%s</a>',
|
||||
translate("Set the node to be used as a pre-proxy.") .. "\n" .. translate("Each rule has a separate switch that controls whether this rule uses the pre-proxy or not."),
|
||||
translate("Preproxy")))
|
||||
proxy_tag_node.template = appname .. "/cbi/nodes_listvalue"
|
||||
proxy_tag_node.template = m:template_path("/cbi/nodes_listvalue")
|
||||
proxy_tag_node.group = {""}
|
||||
proxy_tag_node:value("", translate("Close (Not use)"))
|
||||
proxy_tag_node.cfgvalue = function(self, section)
|
||||
@@ -203,10 +203,4 @@ for k1, v1 in pairs(node_list) do
|
||||
end
|
||||
end
|
||||
|
||||
local footer = Template(appname .. "/include/shunt_options")
|
||||
footer.api = api
|
||||
footer.config = m.config
|
||||
footer.id = current_node_id
|
||||
footer.s_cfgid = s_cfgid or current_node_id
|
||||
footer.normal_list = api.jsonc.stringify(node_list.normal_list)
|
||||
m:append(footer)
|
||||
m:appendTemplate("/include/shunt_options", {id = current_node_id, s_cfgid = s_cfgid or current_node_id, normal_list = api.jsonc.stringify(node_list.normal_list)})
|
||||
@@ -1,30 +1,22 @@
|
||||
api = require "luci.passwall.api"
|
||||
appname = "passwall"
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname, translate("Node Config"))
|
||||
m = Map()
|
||||
m.redirect = api.url("node_list")
|
||||
api.set_apply_on_parse(m)
|
||||
|
||||
if not arg[1] or not m:get(arg[1]) then
|
||||
luci.http.redirect(m.redirect)
|
||||
end
|
||||
|
||||
fs = require "nixio.fs"
|
||||
formvalue_key = "cbid." .. appname .. "." .. arg[1] .. "."
|
||||
formvalue_key = "cbid." .. m.config .. "." .. arg[1] .. "."
|
||||
|
||||
local header = Template(appname .. "/node_config/header")
|
||||
header.api = api
|
||||
header.config = m.config
|
||||
header.section = arg[1]
|
||||
m:append(header)
|
||||
|
||||
m:append(Template(appname .. "/cbi/nodes_multivalue_com"))
|
||||
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
|
||||
m:appendTemplate("/node_config/header", {section = arg[1]})
|
||||
m:appendTemplate("/cbi/nodes_multivalue_com")
|
||||
m:appendTemplate("/cbi/nodes_listvalue_com")
|
||||
|
||||
groups = {}
|
||||
m.uci:foreach(appname, "nodes", function(s)
|
||||
m:foreach("nodes", function(s)
|
||||
if s[".name"] ~= arg[1] then
|
||||
if s.group and s.group ~= "" then
|
||||
groups[s.group] = true
|
||||
@@ -32,13 +24,13 @@ m.uci:foreach(appname, "nodes", function(s)
|
||||
end
|
||||
end)
|
||||
|
||||
s = m:section(NamedSection, arg[1], "nodes", "")
|
||||
s = m:section(NamedSection, arg[1], "nodes", translate("Node Config"))
|
||||
s.addremove = false
|
||||
s.dynamic = false
|
||||
|
||||
o = s:option(DummyValue, "passwall", " ")
|
||||
o.rawhtml = true
|
||||
o.template = "passwall/node_config/link_share_man"
|
||||
o.template = m:template_path("/node_config/link_share_man")
|
||||
o.value = arg[1]
|
||||
|
||||
o = s:option(Value, "remarks", translate("Node Remarks"))
|
||||
@@ -67,10 +59,10 @@ o.write = function(self, section, value)
|
||||
m:set(section, self.option, value)
|
||||
end
|
||||
|
||||
local types_dir = "/usr/lib/lua/luci/model/cbi/passwall/client/type/"
|
||||
local types_dir = "/usr/lib/lua/luci/model/cbi/" .. api.appname .. "/client/type/"
|
||||
s.val = {}
|
||||
s.val["type"] = m.uci:get(appname, arg[1], "type")
|
||||
s.val["protocol"] = m.uci:get(appname, arg[1], "protocol")
|
||||
s.val["type"] = m:get(arg[1], "type")
|
||||
s.val["protocol"] = m:get(arg[1], "protocol")
|
||||
|
||||
if luci.http.formvalue("cbi.submit") == "1" then
|
||||
local formvalue_type = luci.http.formvalue(formvalue_key .. "type")
|
||||
@@ -118,10 +110,6 @@ for index, value in ipairs(type_table) do
|
||||
setfenv(p_func, getfenv(1))(m, s)
|
||||
end
|
||||
|
||||
local footer = Template(appname .. "/node_config/footer")
|
||||
footer.api = api
|
||||
footer.config = m.config
|
||||
footer.section = arg[1]
|
||||
m:append(footer)
|
||||
m:appendTemplate("/node_config/footer", {section = arg[1]})
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -1,14 +1,10 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = "passwall"
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
-- [[ Other Settings ]]--
|
||||
s = m:section(TypedSection, "global_other")
|
||||
s.anonymous = true
|
||||
s = m:section(NamedSection, "@global_other[0]", "global_other")
|
||||
|
||||
o = s:option(ListValue, "auto_detection_time", translate("Automatic detection delay"))
|
||||
o:value("0", translate("Close"))
|
||||
@@ -29,10 +25,7 @@ o:value("https://wifi.vivo.com.cn/generate_204", "VIVO (CN)")
|
||||
o.default = o.keylist[3]
|
||||
|
||||
if true then
|
||||
local o = Template(appname .. "/node_list/node_list")
|
||||
o.map = m
|
||||
o.api = api
|
||||
m:append(o)
|
||||
m:appendTemplate("/node_list/node_list")
|
||||
|
||||
if luci.http.formvalue("cbi.submit") == "1" then
|
||||
local group_order = {}
|
||||
@@ -45,7 +38,7 @@ if true then
|
||||
new_order[#new_order + 1] = w
|
||||
end)
|
||||
for idx, name in ipairs(new_order) do
|
||||
m.uci:reorder(appname, name, idx - 1)
|
||||
m.uci:reorder(m.config, name, idx - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local uci = api.uci
|
||||
local appname = "passwall"
|
||||
api.set_default_cbi()
|
||||
|
||||
local has_ss_rust = api.is_finded("sslocal")
|
||||
local has_singbox = api.finded_com("sing-box")
|
||||
local has_xray = api.finded_com("xray")
|
||||
@@ -38,23 +38,16 @@ if has_hysteria2 then
|
||||
table.insert(hysteria2_type, s)
|
||||
end
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
function m.on_before_save(self)
|
||||
if self.no_commit then
|
||||
return
|
||||
end
|
||||
self.uci:foreach(appname, "subscribe_list", function(e)
|
||||
self:foreach("subscribe_list", function(e)
|
||||
self:del(e[".name"], "md5")
|
||||
end)
|
||||
end
|
||||
|
||||
-- [[ Subscribe Settings ]]--
|
||||
s = m:section(TypedSection, "global_subscribe", "")
|
||||
s.anonymous = true
|
||||
s = m:section(NamedSection, "@global_subscribe[0]", "global_subscribe")
|
||||
|
||||
o = s:option(ListValue, "filter_keyword_mode", translate("Filter keyword Mode"))
|
||||
o:value("0", translate("Close"))
|
||||
@@ -129,15 +122,13 @@ o.cfgvalue = function(self, section)
|
||||
translate("Manual subscription All"))
|
||||
end
|
||||
|
||||
local cfgname = "subscribe_list"
|
||||
s = m:section(TypedSection, cfgname, "", "<font color='red'>" .. translate("When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically.") .. "</font>")
|
||||
s = m:section(TypedSection, "subscribe_list", "", "<font color='red'>" .. translate("When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically.") .. "</font>")
|
||||
s.addremove = true
|
||||
s.anonymous = true
|
||||
s.sortable = true
|
||||
s.template = "cbi/tblsection"
|
||||
s.extedit = api.url("node_subscribe_config", "%s")
|
||||
function s.create(e, t)
|
||||
m.no_commit = true
|
||||
local uid = "sub_" .. api.gen_random_char(5)
|
||||
TypedSection.create(e, uid)
|
||||
m:set(uid, "hysteria_up_mbps", "100")
|
||||
@@ -154,7 +145,7 @@ o.validate = function(self, value, section)
|
||||
return nil, translate("Remark cannot be empty.")
|
||||
end
|
||||
local duplicate = false
|
||||
m.uci:foreach(appname, cfgname, function(e)
|
||||
m:foreach(s.sectiontype, function(e)
|
||||
if e[".name"] ~= section and e["remark"] and e["remark"]:lower() == value:lower() then
|
||||
duplicate = true
|
||||
return false
|
||||
@@ -168,9 +159,9 @@ end
|
||||
o.write = function(self, section, value)
|
||||
local old = m:get(section, self.option) or ""
|
||||
if old ~= value then
|
||||
m.uci:foreach(appname, "nodes", function(e)
|
||||
m:foreach("nodes", function(e)
|
||||
if e["group"] and e["group"]:lower() == old:lower() then
|
||||
m.uci:set(appname, e[".name"], "group", value)
|
||||
m:set(e[".name"], "group", value)
|
||||
end
|
||||
if e["protocol"] and (e["protocol"] == "_balancing" or e["protocol"] == "_urltest") and e["node_group"] then
|
||||
local gs = ""
|
||||
@@ -182,7 +173,7 @@ o.write = function(self, section, value)
|
||||
end
|
||||
end
|
||||
gs = api.trim(gs)
|
||||
m.uci:set(appname, e[".name"], "node_group", gs)
|
||||
m:set(e[".name"], "node_group", gs)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -200,7 +191,7 @@ o.cfgvalue = function(t, n)
|
||||
end
|
||||
str = str ~= "" and "<br>" .. str or ""
|
||||
local num = 0
|
||||
m.uci:foreach(appname, "nodes", function(s)
|
||||
m:foreach("nodes", function(s)
|
||||
if s["group"] and s["group"]:lower() == remark:lower() then
|
||||
num = num + 1
|
||||
end
|
||||
@@ -229,11 +220,8 @@ o.cfgvalue = function(self, section)
|
||||
section, translate("Manual subscription"))
|
||||
end
|
||||
|
||||
local sortable = Template(appname .. "/cbi/sortable")
|
||||
sortable.api = api
|
||||
sortable.target_cfgname = cfgname
|
||||
m:append(sortable)
|
||||
m:appendTemplate("/cbi/sortable", {sectiontype = s.sectiontype})
|
||||
|
||||
m:append(Template(appname .. "/node_subscribe/js"))
|
||||
m:appendTemplate("/node_subscribe/js")
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -1,12 +1,8 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local uci = api.uci
|
||||
local appname = "passwall"
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
m = Map()
|
||||
m.redirect = api.url("node_subscribe")
|
||||
api.set_apply_on_parse(m)
|
||||
|
||||
if not arg[1] or not m:get(arg[1]) then
|
||||
luci.http.redirect(m.redirect)
|
||||
@@ -16,7 +12,7 @@ function m.on_before_save(self)
|
||||
self:del(arg[1], "md5")
|
||||
end
|
||||
|
||||
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
|
||||
m:appendTemplate("/cbi/nodes_listvalue_com")
|
||||
|
||||
local has_ss_rust = api.is_finded("sslocal")
|
||||
local has_singbox = api.finded_com("sing-box")
|
||||
@@ -80,7 +76,7 @@ o.validate = function(self, value, section)
|
||||
return nil, translate("Remark cannot be empty.")
|
||||
end
|
||||
local duplicate = false
|
||||
m.uci:foreach(appname, "subscribe_list", function(e)
|
||||
m:foreach("subscribe_list", function(e)
|
||||
if e[".name"] ~= section and e["remark"] and e["remark"]:lower() == value:lower() then
|
||||
duplicate = true
|
||||
return false
|
||||
@@ -94,9 +90,9 @@ end
|
||||
o.write = function(self, section, value)
|
||||
local old = m:get(section, self.option) or ""
|
||||
if old ~= value then
|
||||
m.uci:foreach(appname, "nodes", function(e)
|
||||
m:foreach("nodes", function(e)
|
||||
if e["group"] and e["group"]:lower() == old:lower() then
|
||||
m.uci:set(appname, e[".name"], "group", value)
|
||||
self:set(e[".name"], "group", value)
|
||||
end
|
||||
if e["protocol"] and (e["protocol"] == "_balancing" or e["protocol"] == "_urltest") and e["node_group"] then
|
||||
local gs = ""
|
||||
@@ -108,7 +104,7 @@ o.write = function(self, section, value)
|
||||
end
|
||||
end
|
||||
gs = api.trim(gs)
|
||||
m.uci:set(appname, e[".name"], "node_group", gs)
|
||||
self:set(e[".name"], "node_group", gs)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -295,13 +291,13 @@ descrStr = translate(descrStr) .. "<br>" .. translate("Only support a layer of p
|
||||
o1 = s:option(ListValue, "preproxy_node", translate("Preproxy Node"))
|
||||
o1:depends({ ["chain_proxy"] = "1" })
|
||||
o1.description = descrStr
|
||||
o1.template = appname .. "/cbi/nodes_listvalue"
|
||||
o1.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o1.group = {}
|
||||
|
||||
o2 = s:option(ListValue, "to_node", translate("Landing Node"))
|
||||
o2:depends({ ["chain_proxy"] = "2" })
|
||||
o2.description = descrStr
|
||||
o2.template = appname .. "/cbi/nodes_listvalue"
|
||||
o2.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o2.group = {}
|
||||
|
||||
o3 = s:option(Value, "outbound_iface", translate("Outbound Interface"))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = "passwall"
|
||||
api.set_default_cbi()
|
||||
|
||||
local fs = api.fs
|
||||
local has_singbox = api.finded_com("sing-box")
|
||||
local has_xray = api.finded_com("xray")
|
||||
@@ -8,15 +9,10 @@ local port_validate = function(self, value, t)
|
||||
return value:gsub("-", ":")
|
||||
end
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
-- [[ Delay Settings ]]--
|
||||
s = m:section(TypedSection, "global_delay", translate("Delay Settings"))
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
s = m:section(NamedSection, "@global_delay[0]", "global_delay", translate("Delay Settings"))
|
||||
|
||||
---- Open and close Daemon
|
||||
o = s:option(Flag, "start_daemon", translate("Open and close Daemon"))
|
||||
@@ -61,9 +57,7 @@ for index, value in ipairs({"stop", "start", "restart"}) do
|
||||
end
|
||||
|
||||
-- [[ Forwarding Settings ]]--
|
||||
s = m:section(TypedSection, "global_forwarding", translate("Forwarding Settings"))
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
s = m:section(NamedSection, "@global_forwarding[0]", "global_forwarding", translate("Forwarding Settings"))
|
||||
|
||||
---- TCP No Redir Ports
|
||||
o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports"))
|
||||
@@ -168,9 +162,7 @@ o:depends("ipv6_tproxy", true)
|
||||
o.default = 0
|
||||
|
||||
if has_xray then
|
||||
s_xray = m:section(TypedSection, "global_xray", "Xray " .. translate("Settings"))
|
||||
s_xray.anonymous = true
|
||||
s_xray.addremove = false
|
||||
s_xray = m:section(NamedSection, "@global_xray[0]", "global_xray", "Xray " .. translate("Settings"))
|
||||
|
||||
o = s_xray:option(Flag, "fragment", translate("Fragment"), translate("TCP fragments, which can deceive the censorship system in some cases, such as bypassing SNI blacklists."))
|
||||
o.default = 0
|
||||
@@ -204,7 +196,7 @@ if has_xray then
|
||||
o.default = 0
|
||||
o.description = translate("Override the connection destination address with the sniffed domain.<br />Otherwise use sniffed domain for routing only.<br />If using shunt nodes, configure the domain shunt rules correctly.")
|
||||
|
||||
local domains_excluded = string.format("/usr/share/%s/rules/domains_excluded", appname)
|
||||
local domains_excluded = string.format("/usr/share/%s/domains_excluded", m.config)
|
||||
o = s_xray:option(TextValue, "excluded_domains", translate("Excluded Domains"), translate("If the traffic sniffing result is in this list, the destination address will not be overridden."))
|
||||
o.rows = 15
|
||||
o.wrap = "off"
|
||||
@@ -227,11 +219,14 @@ if has_xray then
|
||||
end
|
||||
|
||||
s_xray_noise.remove = function(self, section)
|
||||
for k, v in pairs(self.children) do
|
||||
v.rmempty = true
|
||||
v.validate = nil
|
||||
local o = m:get(section) or {}
|
||||
if o[".type"] == self.sectiontype then
|
||||
for k, v in pairs(self.children) do
|
||||
v.rmempty = true
|
||||
v.validate = nil
|
||||
end
|
||||
TypedSection.remove(self, section)
|
||||
end
|
||||
TypedSection.remove(self, section)
|
||||
end
|
||||
|
||||
o = s_xray_noise:option(Flag, "enabled", translate("Enable"))
|
||||
@@ -255,9 +250,7 @@ if has_xray then
|
||||
end
|
||||
|
||||
if has_singbox then
|
||||
s = m:section(TypedSection, "global_singbox", "Sing-Box " .. translate("Settings"))
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
s = m:section(NamedSection, "@global_singbox[0]", "global_singbox", "Sing-Box " .. translate("Settings"))
|
||||
|
||||
o = s:option(Flag, "record_fragment", "TLS Record " .. translate("Fragment"),
|
||||
translate("Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first."))
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = "passwall"
|
||||
local has_xray = api.finded_com("xray")
|
||||
local has_singbox = api.finded_com("sing-box")
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
-- [[ Rule Settings ]]--
|
||||
s = m:section(TypedSection, "global_rules", translate("Rule status"))
|
||||
s.anonymous = true
|
||||
s = m:section(NamedSection, "@global_rules[0]", "global_rules", translate("Rule status"))
|
||||
|
||||
--[[
|
||||
o = s:option(Flag, "adblock", translate("Enable adblock"))
|
||||
@@ -143,12 +139,10 @@ for _, f in ipairs(flags) do
|
||||
o.rmempty = false
|
||||
end
|
||||
|
||||
s:append(Template(appname .. "/rule/rule_version"))
|
||||
s:appendTemplate("/rule/rule_version")
|
||||
|
||||
if has_xray or has_singbox then
|
||||
local o = Template(appname .. "/rule/shunt_rule_list")
|
||||
o.api = api
|
||||
m:append(o)
|
||||
m:appendTemplate("/rule/shunt_rule_list")
|
||||
|
||||
if luci.http.formvalue("cbi.submit") == "1" then
|
||||
local group_order = luci.http.formvaluetable("group.order")
|
||||
@@ -160,7 +154,7 @@ if has_xray or has_singbox then
|
||||
new_order[#new_order + 1] = w
|
||||
end)
|
||||
for idx, name in ipairs(new_order) do
|
||||
m.uci:reorder(appname, name, idx - 1)
|
||||
m.uci:reorder(m.config, name, idx - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = api.appname
|
||||
local fs = api.fs
|
||||
local sys = api.sys
|
||||
local uci = api.uci
|
||||
local datatypes = api.datatypes
|
||||
local path = string.format("/usr/share/%s/rules/", appname)
|
||||
local path = string.format("/usr/share/%s/rules/", api.c_config)
|
||||
local gfwlist_path = "/usr/share/passwall/rules/gfwlist"
|
||||
local chnlist_path = "/usr/share/passwall/rules/chnlist"
|
||||
local chnroute_path = "/usr/share/passwall/rules/chnroute"
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
function clean_text(text)
|
||||
local nbsp = string.char(0xC2, 0xA0) -- 不间断空格(U+00A0)
|
||||
@@ -319,9 +317,9 @@ if fs.access(chnroute_path) then
|
||||
]], translate("Read List"))
|
||||
end
|
||||
|
||||
m:append(Template(appname .. "/rule_list/js"))
|
||||
m:appendTemplate("/rule_list/js")
|
||||
|
||||
local geo_dir = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/")
|
||||
local geo_dir = (uci:get(api.c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/")
|
||||
local geosite_path = geo_dir .. "/geosite.dat"
|
||||
local geoip_path = geo_dir .. "/geoip.dat"
|
||||
if api.finded_com("geoview") and fs.access(geosite_path) and fs.access(geoip_path) then
|
||||
@@ -329,7 +327,7 @@ if api.finded_com("geoview") and fs.access(geosite_path) and fs.access(geoip_pat
|
||||
s:tab("geoview", translate("Geo View"))
|
||||
o = s:taboption("geoview", DummyValue, "_geoview_fieldset")
|
||||
o.rawhtml = true
|
||||
o.template = appname .. "/rule_list/geoview"
|
||||
o.template = m:template_path("/rule_list/geoview")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = "passwall"
|
||||
local datatypes = api.datatypes
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname, "Sing-Box/Xray " .. translate("Shunt Rule"))
|
||||
local datatypes = api.datatypes
|
||||
|
||||
m = Map()
|
||||
m.redirect = api.url("rule")
|
||||
api.set_apply_on_parse(m)
|
||||
|
||||
if not arg[1] or not m:get(arg[1]) then
|
||||
luci.http.redirect(m.redirect)
|
||||
end
|
||||
|
||||
m.on_before_save = function(self)
|
||||
m:set("@global[0]", "flush_set", "1")
|
||||
function m.on_before_save(self)
|
||||
self:set("@global[0]", "flush_set", "1")
|
||||
end
|
||||
|
||||
-- Add inline CSS to map description
|
||||
@@ -46,7 +44,7 @@ end
|
||||
|
||||
local remarks_lookup = {}
|
||||
local groups = {}
|
||||
m.uci:foreach(appname, "shunt_rules", function(s)
|
||||
m:foreach("shunt_rules", function(s)
|
||||
if s[".name"] ~= arg[1] then
|
||||
if s.remarks then
|
||||
remarks_lookup[s.remarks] = s[".name"]
|
||||
@@ -57,7 +55,7 @@ m.uci:foreach(appname, "shunt_rules", function(s)
|
||||
end
|
||||
end)
|
||||
|
||||
s = m:section(NamedSection, arg[1], "shunt_rules", "")
|
||||
s = m:section(NamedSection, arg[1], "shunt_rules", "Sing-Box/Xray " .. translate("Shunt Rule"))
|
||||
s.addremove = false
|
||||
s.dynamic = false
|
||||
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = "passwall"
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
m.redirect = api.url()
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
if not arg[1] or not m:get(arg[1]) then
|
||||
luci.http.redirect(m.redirect)
|
||||
end
|
||||
|
||||
m:append(Template(appname .. "/cbi/nodes_dynamiclist_com"))
|
||||
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
|
||||
m:appendTemplate("/cbi/nodes_dynamiclist_com")
|
||||
m:appendTemplate("/cbi/nodes_listvalue_com")
|
||||
|
||||
local has_singbox = api.finded_com("sing-box")
|
||||
local has_xray = api.finded_com("xray")
|
||||
@@ -50,14 +46,14 @@ socks_node = s:option(ListValue, "node", translate("Node"))
|
||||
if auto_switch_tip then
|
||||
socks_node.description = auto_switch_tip
|
||||
end
|
||||
socks_node.template = appname .. "/cbi/nodes_listvalue"
|
||||
socks_node.template = m:template_path("/cbi/nodes_listvalue")
|
||||
socks_node.group = {}
|
||||
|
||||
o = s:option(Flag, "bind_local", translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
|
||||
o.default = "0"
|
||||
|
||||
local n = 1
|
||||
m.uci:foreach(appname, "socks", function(s)
|
||||
m:foreach("socks", function(s)
|
||||
if s[".name"] == section then
|
||||
return false
|
||||
end
|
||||
@@ -91,7 +87,7 @@ o:value("batch", translate("Batch"))
|
||||
|
||||
o = s:option(DynamicList, "autoswitch_backup_node", translate("List of backup nodes"))
|
||||
o:depends("backup_node_add_mode", "manual")
|
||||
o.template = appname .. "/cbi/nodes_dynamiclist"
|
||||
o.template = m:template_path("/cbi/nodes_dynamiclist")
|
||||
o.group = {}
|
||||
o.write = function(self, section, value)
|
||||
local n = s.fields["node"]:formvalue(section)
|
||||
@@ -117,7 +113,7 @@ o:depends("backup_node_add_mode", "batch")
|
||||
o.widget = "checkbox"
|
||||
o:value("default", translate("default"))
|
||||
local groups = {}
|
||||
m.uci:foreach(appname, "nodes", function(s)
|
||||
m:foreach("nodes", function(s)
|
||||
if s.group and s.group ~= "" then
|
||||
groups[s.group] = true
|
||||
end
|
||||
@@ -165,7 +161,7 @@ o.default = o.keylist[3]
|
||||
o:depends("enable_autoswitch", true)
|
||||
|
||||
o = s:option(DummyValue, "btn")
|
||||
o.template = appname .. "/socks_auto_switch/btn"
|
||||
o.template = m:template_path("/socks_auto_switch/btn")
|
||||
o:depends("backup_node_add_mode", "manual")
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -105,7 +105,7 @@ if load_balancing_options then -- [[ Load balancing Start ]]
|
||||
o = s:option(MultiValue, _n("balancing_node"), translate("Load balancing node list"), translate("Load balancing node list, <a target='_blank' href='https://xtls.github.io/config/routing.html#balancerobject'>document</a>"))
|
||||
o:depends({ [_n("node_add_mode")] = "manual" })
|
||||
o.widget = "checkbox"
|
||||
o.template = appname .. "/cbi/nodes_multivalue"
|
||||
o.template = m:template_path("/cbi/nodes_multivalue")
|
||||
o.group = {}
|
||||
for k1, v1 in pairs(node_list) do
|
||||
if k1 == "socks_list" or k1 == "normal_list" then
|
||||
@@ -171,7 +171,7 @@ if load_balancing_options then -- [[ Load balancing Start ]]
|
||||
o:value("", translate("Close(Not use)"))
|
||||
o:value("_direct", translate("Direct Connection"))
|
||||
o:depends({ [_n("protocol")] = "_balancing" })
|
||||
o.template = appname .. "/cbi/nodes_listvalue"
|
||||
o.template = m:template_path("/cbi/nodes_listvalue")
|
||||
-- 最大 fallback 套娃层数
|
||||
local MAX_FALLBACK_DEPTH = 3
|
||||
-- 检查是否会形成回环
|
||||
@@ -855,7 +855,7 @@ if not load_shunt_options then
|
||||
|
||||
o1 = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
|
||||
o1:depends({ [_n("chain_proxy")] = "1", [_n("hysteria2_realms")] = false })
|
||||
o1.template = appname .. "/cbi/nodes_listvalue"
|
||||
o1.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o1.group = {}
|
||||
|
||||
o3 = s:option(Value, _n("outbound_iface"), translate("Outbound Interface"))
|
||||
@@ -867,7 +867,7 @@ if not load_shunt_options then
|
||||
|
||||
o2 = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
|
||||
o2:depends({ [_n("chain_proxy")] = "2", [_n("hysteria2_realms")] = false })
|
||||
o2.template = appname .. "/cbi/nodes_listvalue"
|
||||
o2.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o2.group = {}
|
||||
|
||||
for k1, v1 in pairs(node_list) do
|
||||
@@ -890,7 +890,7 @@ end
|
||||
api.luci_types(arg[1], m, s, type_name, option_prefix)
|
||||
|
||||
if load_shunt_options then
|
||||
local current_node = m.uci:get_all(appname, arg[1]) or {}
|
||||
local current_node = m:get(arg[1]) or {}
|
||||
local shunt_lua = loadfile("/usr/lib/lua/luci/model/cbi/passwall/client/include/shunt_options.lua")
|
||||
setfenv(shunt_lua, getfenv(1))(m, s, {
|
||||
node_id = arg[1],
|
||||
|
||||
@@ -104,7 +104,7 @@ if load_urltest_options then -- [[ URLTest Start ]]
|
||||
o = s:option(MultiValue, _n("urltest_node"), translate("URLTest node list"), translate("List of nodes to test, <a target='_blank' href='https://sing-box.sagernet.org/configuration/outbound/urltest'>document</a>"))
|
||||
o:depends({ [_n("node_add_mode")] = "manual" })
|
||||
o.widget = "checkbox"
|
||||
o.template = appname .. "/cbi/nodes_multivalue"
|
||||
o.template = m:template_path("/cbi/nodes_multivalue")
|
||||
o.group = {}
|
||||
for k1, v1 in pairs(node_list) do
|
||||
if k1 == "socks_list" or k1 == "normal_list" then
|
||||
@@ -876,7 +876,7 @@ if not load_shunt_options then
|
||||
|
||||
o1 = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
|
||||
o1:depends({ [_n("chain_proxy")] = "1", [_n("hysteria2_realms")] = false })
|
||||
o1.template = appname .. "/cbi/nodes_listvalue"
|
||||
o1.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o1.group = {}
|
||||
|
||||
o3 = s:option(Value, _n("outbound_iface"), translate("Outbound Interface"))
|
||||
@@ -888,7 +888,7 @@ if not load_shunt_options then
|
||||
|
||||
o2 = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
|
||||
o2:depends({ [_n("chain_proxy")] = "2", [_n("hysteria2_realms")] = false })
|
||||
o2.template = appname .. "/cbi/nodes_listvalue"
|
||||
o2.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o2.group = {}
|
||||
|
||||
for k1, v1 in pairs(node_list) do
|
||||
@@ -911,7 +911,7 @@ end
|
||||
api.luci_types(arg[1], m, s, type_name, option_prefix)
|
||||
|
||||
if load_shunt_options then
|
||||
local current_node = m.uci:get_all(appname, arg[1]) or {}
|
||||
local current_node = m:get(arg[1]) or {}
|
||||
local shunt_lua = loadfile("/usr/lib/lua/luci/model/cbi/passwall/client/include/shunt_options.lua")
|
||||
setfenv(shunt_lua, getfenv(1))(m, s, {
|
||||
node_id = arg[1],
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = api.appname
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map("passwall_server", translate("Server-Side"))
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map(api.s_config)
|
||||
|
||||
t = m:section(NamedSection, "global", "global")
|
||||
t = m:section(NamedSection, "global", "global", translate("Server-Side"))
|
||||
t.anonymous = true
|
||||
t.addremove = false
|
||||
|
||||
@@ -94,17 +91,9 @@ e = s_server:option(Flag, "log", translate("Log"))
|
||||
e.default = "1"
|
||||
e.rmempty = false
|
||||
|
||||
local sortable = Template(appname .. "/cbi/sortable")
|
||||
sortable.api = api
|
||||
sortable.appname = m.config
|
||||
sortable.target_cfgname = s_server.sectiontype
|
||||
m:append(sortable)
|
||||
m:appendTemplate("/cbi/sortable", {sectiontype = s_server.sectiontype})
|
||||
|
||||
local server_list_status = Template(appname .. "/server/server_list_status")
|
||||
server_list_status.api = api
|
||||
server_list_status.appname = m.config
|
||||
server_list_status.sectiontype = s_server.sectiontype
|
||||
m:append(server_list_status)
|
||||
m:appendTemplate("/server/server_list_status", {sectiontype = s_server.sectiontype})
|
||||
|
||||
s_user = m:section(TypedSection, "user", translate("Users Manager"))
|
||||
s_user.anonymous = true
|
||||
@@ -120,7 +109,7 @@ end
|
||||
s_user.remove = function(self, section)
|
||||
local o = m:get(section) or {}
|
||||
if o[".type"] == self.sectiontype then
|
||||
m.uci:foreach(m.config, "server", function(o)
|
||||
m:foreach("server", function(o)
|
||||
if o.user and section == o.user then
|
||||
m:set(o[".name"], "user", "")
|
||||
end
|
||||
@@ -150,12 +139,8 @@ e.width = "25%"
|
||||
e = s_user:option(DummyValue, "uuid", "UUID")
|
||||
e.width = "25%"
|
||||
|
||||
local sortable = Template(appname .. "/cbi/sortable")
|
||||
sortable.api = api
|
||||
sortable.appname = m.config
|
||||
sortable.target_cfgname = s_user.sectiontype
|
||||
m:append(sortable)
|
||||
m:appendTemplate("/cbi/sortable", {sectiontype = s_user.sectiontype})
|
||||
|
||||
m:append(Template(appname .. "/server/log"))
|
||||
m:appendTemplate("/server/log")
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -1,35 +1,27 @@
|
||||
api = require "luci.passwall.api"
|
||||
appname = api.appname
|
||||
fs = api.fs
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map("passwall_server", translate("Server Config"))
|
||||
m = Map(api.s_config)
|
||||
m.redirect = api.url("server")
|
||||
api.set_apply_on_parse(m)
|
||||
|
||||
if not arg[1] or not m:get(arg[1]) then
|
||||
luci.http.redirect(m.redirect)
|
||||
end
|
||||
|
||||
local header = Template(appname .. "/server/config_header")
|
||||
header.api = api
|
||||
header.config = m.config
|
||||
header.section = arg[1]
|
||||
m:append(header)
|
||||
m:appendTemplate("/server/config_header", {section = arg[1]})
|
||||
|
||||
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
|
||||
m:appendTemplate("/cbi/nodes_listvalue_com")
|
||||
|
||||
user_list = {}
|
||||
m.uci:foreach(m.config, "user", function(s)
|
||||
m:foreach("user", function(s)
|
||||
user_list[#user_list + 1] = s
|
||||
end)
|
||||
|
||||
s = m:section(NamedSection, arg[1], "server", "")
|
||||
s = m:section(NamedSection, arg[1], "server", translate("Server Config"))
|
||||
s.addremove = false
|
||||
s.dynamic = false
|
||||
|
||||
local types_dir = "/usr/lib/lua/luci/model/cbi/" .. appname .. "/server/type/"
|
||||
local types_dir = "/usr/lib/lua/luci/model/cbi/" .. api.appname .. "/server/type/"
|
||||
s.val = m:get(arg[1]) or {}
|
||||
|
||||
o = s:option(Flag, "enable", translate("Enable"))
|
||||
@@ -43,7 +35,7 @@ o.rmempty = false
|
||||
o = s:option(ListValue, "type", translate("Type"))
|
||||
|
||||
local type_table = {}
|
||||
for filename in fs.dir(types_dir) do
|
||||
for filename in api.fs.dir(types_dir) do
|
||||
table.insert(type_table, filename)
|
||||
end
|
||||
table.sort(type_table, function(a, b)
|
||||
@@ -57,10 +49,6 @@ for index, value in ipairs(type_table) do
|
||||
setfenv(p_func, getfenv(1))(m, s)
|
||||
end
|
||||
|
||||
local footer = Template(appname .. "/server/config_footer")
|
||||
footer.api = api
|
||||
footer.config = m.config
|
||||
footer.section = arg[1]
|
||||
m:append(footer)
|
||||
m:appendTemplate("/server/config_footer", {section = arg[1]})
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -441,7 +441,7 @@ o:value("", translate("Close"))
|
||||
o:value("_socks", translate("Custom Socks"))
|
||||
o:value("_http", translate("Custom HTTP"))
|
||||
o:value("_iface", translate("Custom Interface"))
|
||||
o.template = api.appname .. "/cbi/nodes_listvalue"
|
||||
o.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o.group = {"","","",""}
|
||||
for k, v in pairs(nodes_table) do
|
||||
o:value(v.id, v.remarks)
|
||||
|
||||
@@ -424,7 +424,7 @@ o:value("", translate("Close"))
|
||||
o:value("_socks", translate("Custom Socks"))
|
||||
o:value("_http", translate("Custom HTTP"))
|
||||
o:value("_iface", translate("Custom Interface"))
|
||||
o.template = api.appname .. "/cbi/nodes_listvalue"
|
||||
o.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o.group = {"","","",""}
|
||||
for k, v in pairs(nodes_table) do
|
||||
o:value(v.id, v.remarks)
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
api = require "luci.passwall.api"
|
||||
appname = api.appname
|
||||
fs = api.fs
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map("passwall_server", translate("User Config"))
|
||||
m = Map(api.s_config)
|
||||
m.redirect = api.url("server")
|
||||
api.set_apply_on_parse(m)
|
||||
|
||||
if not arg[1] or not m:get(arg[1]) then
|
||||
luci.http.redirect(m.redirect)
|
||||
end
|
||||
|
||||
s = m:section(NamedSection, arg[1], "user", "")
|
||||
s = m:section(NamedSection, arg[1], "user", translate("User Config"))
|
||||
s.addremove = false
|
||||
s.dynamic = false
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
module("luci.passwall.api", package.seeall)
|
||||
appname = "passwall"
|
||||
c_config = "passwall"
|
||||
s_config = "passwall_server"
|
||||
local com = require "luci.passwall.com"
|
||||
nixio = require "nixio"
|
||||
fs = require "nixio.fs"
|
||||
@@ -30,10 +33,6 @@ function log(...)
|
||||
end
|
||||
end
|
||||
|
||||
function is_js_luci()
|
||||
return sys.call('[ -f "/www/luci-static/resources/uci.js" ]') == 0
|
||||
end
|
||||
|
||||
function is_old_uci()
|
||||
return sys.call("grep -E 'require[ \t]*\"uci\"' /usr/lib/lua/luci/model/uci.lua >/dev/null 2>&1") == 0
|
||||
end
|
||||
@@ -214,7 +213,7 @@ function curl_direct(url, file, args)
|
||||
end
|
||||
|
||||
function curl_auto(url, file, args)
|
||||
local localhost_proxy = uci:get(appname, "@global[0]", "localhost_proxy") or "1"
|
||||
local localhost_proxy = uci:get(c_config, "@global[0]", "localhost_proxy") or "1"
|
||||
if localhost_proxy == "1" then
|
||||
return curl_base(url, file, args) -- 当路由器本机开启代理时,采用passwall规则进行访问
|
||||
else
|
||||
@@ -482,11 +481,11 @@ function get_domain_from_url(url)
|
||||
end
|
||||
|
||||
function get_valid_nodes()
|
||||
local show_node_info = uci_get_type("global_other", "show_node_info", "0")
|
||||
local show_node_info = uci:get(c_config, "@global_other[0]", "show_node_info") or "0"
|
||||
local nodes = {}
|
||||
local default_nodes = {}
|
||||
local other_nodes = {}
|
||||
uci:foreach(appname, "nodes", function(e)
|
||||
uci:foreach(c_config, "nodes", function(e)
|
||||
e.id = e[".name"]
|
||||
if e.type and e.remarks then
|
||||
local type_name = e.type
|
||||
@@ -559,7 +558,7 @@ function get_node_list()
|
||||
socks_list = {},
|
||||
normal_list = {},
|
||||
}
|
||||
uci:foreach(appname, "socks", function(s)
|
||||
uci:foreach(c_config, "socks", function(s)
|
||||
if s.enabled == "1" and s.node then
|
||||
node_list.socks_list[#node_list.socks_list + 1] = {
|
||||
id = s[".name"],
|
||||
@@ -658,23 +657,7 @@ function gen_random_char(length)
|
||||
return sys.exec("echo -n $(head /dev/urandom | tr -dc A-Za-z0-9 | head -c %s)" % length)
|
||||
end
|
||||
|
||||
function uci_get_type(type, config, default)
|
||||
local value = uci:get_first(appname, type, config, default) or sys.exec("echo -n $(uci -q get " .. appname .. ".@" .. type .."[0]." .. config .. ")")
|
||||
if (value == nil or value == "") and (default and default ~= "") then
|
||||
value = default
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
function uci_get_type_id(id, config, default)
|
||||
local value = uci:get(appname, id, config, default) or sys.exec("echo -n $(uci -q get " .. appname .. "." .. id .. "." .. config .. ")")
|
||||
if (value == nil or value == "") and (default and default ~= "") then
|
||||
value = default
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
local function chmod_755(file)
|
||||
function chmod_755(file)
|
||||
if file and file ~= "" then
|
||||
if not fs.access(file, "rwx", "rx", "rx") then
|
||||
fs.chmod(file, 755)
|
||||
@@ -683,7 +666,7 @@ local function chmod_755(file)
|
||||
end
|
||||
|
||||
function get_customed_path(e)
|
||||
return uci_get_type("global_app", e .. "_file")
|
||||
return uci:get(c_config, "@global_app[0]", e .. "_file")
|
||||
end
|
||||
|
||||
function finded_com(e)
|
||||
@@ -742,7 +725,7 @@ end
|
||||
function get_app_path(app_name)
|
||||
if com[app_name] then
|
||||
local def_path = com[app_name].default_path
|
||||
local path = uci_get_type("global_app", app_name:gsub("%-","_") .. "_file")
|
||||
local path = uci:get(c_config, "@global_app[0]", app_name:gsub("%-","_") .. "_file")
|
||||
path = path and (#path>0 and path or def_path) or def_path
|
||||
return path
|
||||
end
|
||||
@@ -1020,7 +1003,7 @@ local default_file_tree = {
|
||||
}
|
||||
|
||||
local function get_api_json(url)
|
||||
local gh_proxy = uci_get_type("global_app", "github_proxy", "0")
|
||||
local gh_proxy = uci:get(c_config, "@global_app[0]", "github_proxy") or "0"
|
||||
local return_code, content
|
||||
if gh_proxy == "1" then
|
||||
url = "https://gh-proxy.org/" .. url
|
||||
@@ -1144,7 +1127,7 @@ function to_download(app_name, url, size)
|
||||
local _curl_args = clone(curl_args)
|
||||
table.insert(_curl_args, "--speed-limit 51200 --speed-time 15 --max-time 300")
|
||||
|
||||
local gh_proxy = uci_get_type("global_app", "github_proxy", "0")
|
||||
local gh_proxy = uci:get(c_config, "@global_app[0]", "github_proxy") or "0"
|
||||
local return_code, result
|
||||
if gh_proxy == "1" then
|
||||
url = "https://gh-proxy.org/" .. url
|
||||
@@ -1302,7 +1285,7 @@ end
|
||||
function to_check_self()
|
||||
local url = "https://raw.githubusercontent.com/Openwrt-Passwall/openwrt-passwall/main/luci-app-passwall/Makefile"
|
||||
local tmp_file = "/tmp/passwall_makefile"
|
||||
local gh_proxy = uci_get_type("global_app", "github_proxy", "0")
|
||||
local gh_proxy = uci:get(c_config, "@global_app[0]", "github_proxy") or "0"
|
||||
local return_code, result
|
||||
if gh_proxy == "1" then
|
||||
url = "https://gh-proxy.org/" .. url
|
||||
@@ -1339,8 +1322,72 @@ function to_check_self()
|
||||
}
|
||||
end
|
||||
|
||||
function is_js_luci()
|
||||
return sys.call('[ -f "/www/luci-static/resources/uci.js" ]') == 0
|
||||
end
|
||||
|
||||
function set_default_cbi()
|
||||
local cbi = require "luci.cbi"
|
||||
if true then
|
||||
--Map
|
||||
local Map = cbi.Map
|
||||
|
||||
if not Map._passwall_default_cbi then
|
||||
Map._passwall_default_cbi = true
|
||||
local original_parse = Map.parse
|
||||
function Map.parse(self, ...)
|
||||
if is_js_luci() then
|
||||
apply_redirect(self)
|
||||
local old = self.on_after_save
|
||||
self.on_after_save = function(map)
|
||||
if old then old(map) end
|
||||
map:set("@global[0]", "timestamp", os.time())
|
||||
end
|
||||
end
|
||||
return original_parse(self, ...)
|
||||
end
|
||||
end
|
||||
|
||||
local original_init = Map.__init__
|
||||
function Map.__init__(self, config, ...)
|
||||
if not config then config = c_config end
|
||||
original_init(self, config, ...)
|
||||
self.api = require "luci.passwall.api"
|
||||
end
|
||||
function Map.foreach(self, stype, func)
|
||||
self.uci:foreach(self.config, stype, func)
|
||||
end
|
||||
function Map.template_path(self, template)
|
||||
return appname .. template
|
||||
end
|
||||
function Map.appendTemplate(self, template, data)
|
||||
local obj = cbi.Template(self:template_path(template))
|
||||
obj.map = self
|
||||
if data and next(data) then
|
||||
for k, v in pairs(data) do
|
||||
obj[k] = v
|
||||
end
|
||||
end
|
||||
self:append(obj)
|
||||
return obj
|
||||
end
|
||||
end
|
||||
if true then
|
||||
--AbstractSection
|
||||
local AbstractSection = cbi.AbstractSection
|
||||
function AbstractSection.appendTemplate(self, template, data)
|
||||
local obj = cbi.Template(self.map:template_path(template))
|
||||
obj.map = self.map
|
||||
obj.section = self
|
||||
if data and next(data) then
|
||||
for k, v in pairs(data) do
|
||||
obj[k] = v
|
||||
end
|
||||
end
|
||||
self:append(obj)
|
||||
return obj
|
||||
end
|
||||
end
|
||||
if true then
|
||||
--TextValue
|
||||
local TextValue = cbi.TextValue
|
||||
@@ -1377,18 +1424,15 @@ function return_map(map)
|
||||
if true then
|
||||
-- header
|
||||
local header = cbi.Template(appname .. "/cbi/header")
|
||||
header.api = api
|
||||
header.config = map.config
|
||||
header.map = map
|
||||
table.insert(map.children, 1, header)
|
||||
end
|
||||
if true then
|
||||
-- footer
|
||||
local footer = cbi.Template(appname .. "/cbi/footer")
|
||||
footer.api = api
|
||||
footer.config = map.config
|
||||
footer.map = map
|
||||
map:append(footer)
|
||||
end
|
||||
|
||||
return map
|
||||
end
|
||||
|
||||
@@ -1569,20 +1613,8 @@ function format_go_time(input, default)
|
||||
return result
|
||||
end
|
||||
|
||||
function set_apply_on_parse(map)
|
||||
if not map then return end
|
||||
if is_js_luci() then
|
||||
apply_redirect(map)
|
||||
local old = map.on_after_save
|
||||
map.on_after_save = function(self)
|
||||
if old then old(self) end
|
||||
map:set("@global[0]", "timestamp", os.time())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function apply_redirect(m)
|
||||
local tmp_uci_file = "/etc/config/" .. appname .. "_redirect"
|
||||
local tmp_uci_file = "/etc/config/" .. c_config .. "_redirect"
|
||||
if m.redirect and m.redirect ~= "" then
|
||||
if fs.access(tmp_uci_file) then
|
||||
local redirect
|
||||
@@ -1597,10 +1629,14 @@ function apply_redirect(m)
|
||||
else
|
||||
fs.writefile(tmp_uci_file, "config redirect\n")
|
||||
end
|
||||
local old = m.on_after_save
|
||||
m.on_after_save = function(self)
|
||||
if old then
|
||||
old(self)
|
||||
end
|
||||
local redirect = self.redirect
|
||||
if redirect and redirect ~= "" then
|
||||
uci:set(appname .. "_redirect", "@redirect[0]", "url", redirect)
|
||||
uci:set(c_config .. "_redirect", "@redirect[0]", "url", redirect)
|
||||
end
|
||||
end
|
||||
else
|
||||
@@ -1705,7 +1741,7 @@ end
|
||||
function get_socks_backup_nodes(id)
|
||||
id = trim(id)
|
||||
if id == "" then return "" end
|
||||
local socks = uci:get_all(appname, id)
|
||||
local socks = uci:get_all(c_config, id)
|
||||
local nodes
|
||||
if socks.backup_node_add_mode and socks.backup_node_add_mode == "batch" then
|
||||
local node = {}
|
||||
@@ -1726,7 +1762,7 @@ function get_socks_backup_nodes(id)
|
||||
end
|
||||
|
||||
function get_core(field, candidates)
|
||||
local v = uci:get(appname, "@global_subscribe[0]", field)
|
||||
local v = uci:get(c_config, "@global_subscribe[0]", field)
|
||||
if v and v ~= "" then
|
||||
for _, c in ipairs(candidates) do
|
||||
if c[2] == v and c[1] then
|
||||
|
||||
@@ -6,7 +6,7 @@ local sys = api.sys
|
||||
local uci = api.uci
|
||||
local jsonc = api.jsonc
|
||||
|
||||
local CONFIG = "passwall_server"
|
||||
local CONFIG = api.s_config
|
||||
local CONFIG_PATH = "/tmp/etc/" .. CONFIG
|
||||
local NFT_INCLUDE_FILE = CONFIG_PATH .. "/" .. CONFIG .. ".nft"
|
||||
local LOG_APP_FILE = "/tmp/log/" .. CONFIG .. ".log"
|
||||
|
||||
@@ -9,7 +9,7 @@ function gen_config_server(node)
|
||||
if node.users and #node.users > 0 then
|
||||
users = {}
|
||||
for i, v in ipairs(node.users) do
|
||||
local user = uci:get_all("passwall_server", v) or {}
|
||||
local user = uci:get_all(api.s_config, v) or {}
|
||||
if user[".type"] == "user" then
|
||||
users[user.username] = user.password
|
||||
end
|
||||
@@ -74,7 +74,7 @@ function gen_config(var)
|
||||
print("node 不能为空")
|
||||
return
|
||||
end
|
||||
local node = uci:get_all("passwall", node_id)
|
||||
local node = uci:get_all(api.c_config, node_id)
|
||||
local local_tcp_redir_port = var["local_tcp_redir_port"]
|
||||
local local_udp_redir_port = var["local_udp_redir_port"]
|
||||
local local_socks_address = var["local_socks_address"] or "0.0.0.0"
|
||||
|
||||
@@ -9,7 +9,7 @@ function gen_config(var)
|
||||
print("node 不能为空")
|
||||
return
|
||||
end
|
||||
local node = uci:get_all("passwall", node_id)
|
||||
local node = uci:get_all(api.c_config, node_id)
|
||||
local run_type = var["run_type"]
|
||||
local local_addr = var["local_addr"]
|
||||
local local_port = var["local_port"]
|
||||
|
||||
@@ -6,7 +6,7 @@ local jsonc = api.jsonc
|
||||
function gen_config_server(node)
|
||||
local user = nil
|
||||
if node.user then
|
||||
user = uci:get_all("passwall_server", node.user)
|
||||
user = uci:get_all(api.s_config, node.user)
|
||||
end
|
||||
local config = {}
|
||||
config.server_port = tonumber(node.port)
|
||||
@@ -40,7 +40,7 @@ function gen_config(var)
|
||||
print("node 不能为空")
|
||||
return
|
||||
end
|
||||
local node = uci:get_all("passwall", node_id)
|
||||
local node = uci:get_all(api.c_config, node_id)
|
||||
local server_host = var["server_host"] or (node.address or ""):lower()
|
||||
local server_port = var["server_port"] or node.port
|
||||
local local_addr = var["local_addr"]
|
||||
|
||||
@@ -3,7 +3,7 @@ local api = require "luci.passwall.api"
|
||||
local uci = api.uci
|
||||
local sys = api.sys
|
||||
local jsonc = api.jsonc
|
||||
local appname = "passwall"
|
||||
local appname = api.appname
|
||||
local fs = api.fs
|
||||
local ech_domain = {}
|
||||
|
||||
@@ -34,7 +34,7 @@ function check_geoview()
|
||||
if GEO_VAR.OK == 0 then
|
||||
api.log("!!!注意:缺少 Geoview 组件或版本过低,Sing-Box 分流无法启用!")
|
||||
else
|
||||
GEO_VAR.DIR = GEO_VAR.DIR or (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/")
|
||||
GEO_VAR.DIR = GEO_VAR.DIR or (uci:get(api.c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/")
|
||||
GEO_VAR.SITE_PATH = GEO_VAR.SITE_PATH or (GEO_VAR.DIR .. "/geosite.dat")
|
||||
GEO_VAR.IP_PATH = GEO_VAR.IP_PATH or (GEO_VAR.DIR .. "/geoip.dat")
|
||||
if not fs.access(GEO_VAR.TO_SRS_PATH) then
|
||||
@@ -771,7 +771,7 @@ function gen_config_server(node)
|
||||
if node.users and #node.users > 0 then
|
||||
users = {}
|
||||
for i, v in ipairs(node.users) do
|
||||
local user = uci:get_all("passwall_server", v) or {}
|
||||
local user = uci:get_all(api.s_config, v) or {}
|
||||
if user[".type"] == "user" then
|
||||
local u = {}
|
||||
if node.protocol == "mixed" or node.protocol == "socks" or node.protocol == "http" or node.protocol == "naive" then
|
||||
@@ -1008,7 +1008,7 @@ function gen_config_server(node)
|
||||
}
|
||||
sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.outbound_node_iface))
|
||||
else
|
||||
local outbound_node_t = uci:get_all("passwall", node.outbound_node)
|
||||
local outbound_node_t = uci:get_all(api.c_config, node.outbound_node)
|
||||
if node.outbound_node == "_socks" or node.outbound_node == "_http" then
|
||||
outbound_node_t = {
|
||||
type = node.type,
|
||||
@@ -1104,7 +1104,7 @@ function gen_config(var)
|
||||
local rule_set_table = {}
|
||||
local COMMON = {}
|
||||
|
||||
local singbox_settings = uci:get_all(appname, "@global_singbox[0]") or {}
|
||||
local singbox_settings = uci:get_all(api.c_config, "@global_singbox[0]") or {}
|
||||
|
||||
local route = {
|
||||
rules = {}
|
||||
@@ -1166,7 +1166,7 @@ function gen_config(var)
|
||||
end
|
||||
|
||||
if node_id then
|
||||
local node = uci:get_all(appname, node_id)
|
||||
local node = uci:get_all(api.c_config, node_id)
|
||||
if node then
|
||||
if server_host and server_port then
|
||||
node.address = server_host
|
||||
@@ -1256,7 +1256,7 @@ function gen_config(var)
|
||||
|
||||
function get_node_by_id(node_id)
|
||||
if not node_id or node_id == "" or node_id == "nil" then return nil end
|
||||
local section = uci:get_all(appname, node_id) or {}
|
||||
local section = uci:get_all(api.c_config, node_id) or {}
|
||||
if section[".type"] == "socks" then
|
||||
local result = {
|
||||
[".name"] = node_id,
|
||||
@@ -1533,7 +1533,7 @@ function gen_config(var)
|
||||
|
||||
--shunt rule
|
||||
local function foreach_shunt_rule(callback)
|
||||
uci:foreach(appname, "shunt_rules", callback)
|
||||
uci:foreach(api.c_config, "shunt_rules", callback)
|
||||
|
||||
if use_gfw_list ~= "1" or chn_list ~= "0" then return end
|
||||
|
||||
@@ -1559,7 +1559,7 @@ function gen_config(var)
|
||||
|
||||
local bin = api.finded_com("geoview")
|
||||
if bin then
|
||||
local geo_file = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/") .. "/geosite.dat"
|
||||
local geo_file = (uci:get(api.c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/") .. "/geosite.dat"
|
||||
if luci.sys.call('"' .. bin .. '" -type geosite -input "' .. geo_file .. '" | grep -q "^GFW$"') == 0 then
|
||||
domain_list = (domain_list == "") and "geosite:gfw" or domain_list .. "\ngeosite:gfw"
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@ local api = require "luci.passwall.api"
|
||||
local uci = api.uci
|
||||
local sys = api.sys
|
||||
local jsonc = api.jsonc
|
||||
local appname = "passwall"
|
||||
local appname = api.appname
|
||||
local fs = api.fs
|
||||
|
||||
local GLOBAL = {
|
||||
@@ -493,7 +493,7 @@ function gen_config_server(node)
|
||||
if node.users and #node.users > 0 then
|
||||
users = {}
|
||||
for i, v in ipairs(node.users) do
|
||||
local user = uci:get_all("passwall_server", v) or {}
|
||||
local user = uci:get_all(api.s_config, v) or {}
|
||||
if user[".type"] == "user" then
|
||||
local u = {}
|
||||
if node.protocol == "socks" or node.protocol == "http" then
|
||||
@@ -625,7 +625,7 @@ function gen_config_server(node)
|
||||
}
|
||||
sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.outbound_node_iface))
|
||||
else
|
||||
local outbound_node_t = uci:get_all("passwall", node.outbound_node)
|
||||
local outbound_node_t = uci:get_all(api.c_config, node.outbound_node)
|
||||
if node.outbound_node == "_socks" or node.outbound_node == "_http" then
|
||||
outbound_node_t = {
|
||||
type = node.type,
|
||||
@@ -901,7 +901,7 @@ function gen_config(var)
|
||||
local outbounds = {}
|
||||
local COMMON = {}
|
||||
|
||||
local xray_settings = uci:get_all(appname, "@global_xray[0]") or {}
|
||||
local xray_settings = uci:get_all(api.c_config, "@global_xray[0]") or {}
|
||||
|
||||
if xray_settings.fragment == "1" then
|
||||
local lengths, delays = {}, {}
|
||||
@@ -926,7 +926,7 @@ function gen_config(var)
|
||||
|
||||
if xray_settings.noise == "1" then
|
||||
local noises = {}
|
||||
uci:foreach(appname, "xray_noise_packets", function(n)
|
||||
uci:foreach(api.c_config, "xray_noise_packets", function(n)
|
||||
if n.enabled == "1" then
|
||||
local noise = {
|
||||
rand = (n.type == "rand" and n.packet) and (n.packet:find("-", 1, true) and n.packet or tonumber(n.packet)) or nil,
|
||||
@@ -944,7 +944,7 @@ function gen_config(var)
|
||||
end
|
||||
|
||||
if node_id then
|
||||
local node = uci:get_all(appname, node_id)
|
||||
local node = uci:get_all(api.c_config, node_id)
|
||||
local balancers = {}
|
||||
local rules = {}
|
||||
if node then
|
||||
@@ -1001,7 +1001,7 @@ function gen_config(var)
|
||||
|
||||
function get_node_by_id(node_id)
|
||||
if not node_id or node_id == "" or node_id == "nil" then return nil end
|
||||
local section = uci:get_all(appname, node_id) or {}
|
||||
local section = uci:get_all(api.c_config, node_id) or {}
|
||||
if section[".type"] == "socks" then
|
||||
local result = {
|
||||
[".name"] = node_id,
|
||||
@@ -1374,7 +1374,7 @@ function gen_config(var)
|
||||
|
||||
--shunt rule
|
||||
local function foreach_shunt_rule(callback)
|
||||
uci:foreach(appname, "shunt_rules", callback)
|
||||
uci:foreach(api.c_config, "shunt_rules", callback)
|
||||
|
||||
if use_gfw_list ~= "1" or chn_list ~= "0" then return end
|
||||
|
||||
@@ -1400,7 +1400,7 @@ function gen_config(var)
|
||||
|
||||
local bin = api.finded_com("geoview")
|
||||
if bin then
|
||||
local geo_file = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/") .. "/geosite.dat"
|
||||
local geo_file = (uci:get(api.c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/") .. "/geosite.dat"
|
||||
if luci.sys.call('"' .. bin .. '" -type geosite -input "' .. geo_file .. '" | grep -q "^GFW$"') == 0 then
|
||||
domain_list = (domain_list == "") and "geosite:gfw" or domain_list .. "\ngeosite:gfw"
|
||||
end
|
||||
@@ -1788,7 +1788,7 @@ function gen_config(var)
|
||||
})
|
||||
|
||||
-- remote dns outbound
|
||||
local chn_list = uci:get(appname, "@global[0]", "chn_list") or "direct"
|
||||
local chn_list = uci:get(api.c_config, "@global[0]", "chn_list") or "direct"
|
||||
remote_dns_outbound = {
|
||||
tag = "dns-out",
|
||||
protocol = "dns",
|
||||
@@ -1979,7 +1979,7 @@ function gen_config(var)
|
||||
if inbounds or outbounds then
|
||||
local config = {
|
||||
env = (function()
|
||||
local asset_location = uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
|
||||
local asset_location = uci:get(api.c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
|
||||
return { XRAY_LOCATION_ASSET = asset_location }
|
||||
end)(),
|
||||
log = {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<%
|
||||
local api = self.api
|
||||
local cfgid = self.cfgid
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local sid = self.section
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
@@ -20,8 +21,8 @@ local cfgid = self.cfgid
|
||||
return;
|
||||
}
|
||||
let to_url = '<%=api.url("node_config")%>/' + node_select_value;
|
||||
if (node_select_value.indexOf("Socks_") === 0) {
|
||||
to_url = '<%=api.url("socks_config")%>/' + node_select_value.substring("Socks_".length);
|
||||
if (node_select_value.indexOf("socks_") === 0) {
|
||||
to_url = '<%=api.url("socks_config")%>/' + node_select_value;
|
||||
}
|
||||
location.href = to_url;
|
||||
}
|
||||
@@ -50,7 +51,7 @@ local cfgid = self.cfgid
|
||||
|
||||
const m = cbid.match(/\.(tcp|udp)_node$/);
|
||||
if (m && (m[1] === "tcp" || m[1] === "udp")) {
|
||||
html += '<a href="#" onclick="window.open(\'' + '<%=api.url("get_redir_log") .. "?name=" .. cfgid%>&proto=' + m[1] + '\', \'_blank\')"><%:Log%></a>';
|
||||
html += '<a href="#" onclick="window.open(\'' + '<%=api.url("get_redir_log") .. "?name=" .. sid%>&proto=' + m[1] + '\', \'_blank\')"><%:Log%></a>';
|
||||
}
|
||||
|
||||
html = '<div class="node-actions" style="display:inline-flex; align-items:center; gap:4px; flex-wrap:wrap; margin-left:4px;">' + html + '</div>'
|
||||
@@ -112,7 +113,7 @@ local cfgid = self.cfgid
|
||||
logLink.href = "#";
|
||||
logLink.className = "dns-log-link";
|
||||
logLink.style.marginLeft = "10px";
|
||||
logLink.setAttribute("onclick", "window.open('" + '<%=api.url("get_chinadns_log") .. "?flag=" .. cfgid%>' + "', '_blank')");
|
||||
logLink.setAttribute("onclick", "window.open('" + '<%=api.url("get_chinadns_log") .. "?flag=" .. sid%>' + "', '_blank')");
|
||||
select.insertAdjacentElement("afterend", logLink);
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<div id="app_version">
|
||||
<%
|
||||
local api = self.api
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local com = self.com
|
||||
-%>
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
<%
|
||||
local map = self.map
|
||||
-%>
|
||||
<!-- map footer -->
|
||||
<script type="text/javascript">
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
<%
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
<!-- map header -->
|
||||
<script src="<%=resource%>/view/<%=self.api.appname%>/cbi.js"></script>
|
||||
<script src="<%=resource%>/view/<%=self.api.appname%>/func.js"></script>
|
||||
<script src="<%=resource%>/view/<%=api.appname%>/cbi.js"></script>
|
||||
<script src="<%=resource%>/view/<%=api.appname%>/func.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function update_config(cfgid, data, redirect_url) {
|
||||
XHR.get('<%=self.api.url("update_config")%>', {
|
||||
XHR.get('<%=api.url("update_config")%>', {
|
||||
id: cfgid,
|
||||
data: JSON.stringify(data)
|
||||
},
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<%
|
||||
local api = self.api
|
||||
local appname = self.appname or api.appname
|
||||
local target_cfgname = self.target_cfgname
|
||||
local map = self.map
|
||||
local sectiontype = self.sectiontype
|
||||
local api = map.api
|
||||
local appname = self.appname or map.config
|
||||
-%>
|
||||
<script src="<%=resource%>/view/<%=api.appname%>/Sortable.min.js"></script>
|
||||
<style>
|
||||
@@ -37,7 +38,7 @@ local target_cfgname = self.target_cfgname
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1152px) {
|
||||
#cbi-<%=appname%>-<%=target_cfgname%> .cbi-section-table-titles {
|
||||
#cbi-<%=appname%>-<%=sectiontype%> .cbi-section-table-titles {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
@@ -47,7 +48,7 @@ local target_cfgname = self.target_cfgname
|
||||
//Add drag-and-drop sorting
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
function initSortableForTable() {
|
||||
var section = document.getElementById("cbi-<%=appname%>-<%=target_cfgname%>");
|
||||
var section = document.getElementById("cbi-<%=appname%>-<%=sectiontype%>");
|
||||
if (!section) return;
|
||||
|
||||
// === insert drag handle ===
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
|
||||
<div class="cbi-section">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
<style>
|
||||
.dns-con {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<%
|
||||
local api = self.api
|
||||
local appname = api.appname
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local appname = map.config
|
||||
local sid = "@global[0]"
|
||||
-%>
|
||||
<style>
|
||||
#cbi-<%=appname%>-socks .td.cbi-value-field > div {
|
||||
@@ -35,15 +37,17 @@ local appname = api.appname
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
let global_id = "<%=sid%>";
|
||||
const shunt_list = JSON.parse('<%=self.shunt_list%>');
|
||||
|
||||
function to_edit_node(btn) {
|
||||
function to_edit_node(btn, stype) {
|
||||
if (!btn) return;
|
||||
const idReg = /^cbid\..*\..*node$/;
|
||||
if (!stype) return;
|
||||
let hidden_select = null;
|
||||
const container = btn.closest('#cbi-<%=appname%>-global') || btn.closest('#cbi-<%=appname%>-socks');
|
||||
if (!container) return null;
|
||||
const selects = container.querySelectorAll('select[id^="cbid."][id*="."][id$="node"]');
|
||||
const stype_dom = document.getElementById("cbi-<%=appname%>-" + stype);
|
||||
if (!stype_dom) return;
|
||||
const selects = stype_dom.querySelectorAll('select[id^="cbid."][id*="."][id$="node"]');
|
||||
const idReg = /^cbid\..*\..*node$/;
|
||||
for (const sel of selects) {
|
||||
if ( idReg.test(sel.id) && getComputedStyle(sel).display === "none" && (sel.compareDocumentPosition(btn) & Node.DOCUMENT_POSITION_FOLLOWING)) {
|
||||
hidden_select = sel;
|
||||
@@ -94,8 +98,7 @@ local appname = api.appname
|
||||
);
|
||||
}
|
||||
|
||||
let global_id = null;
|
||||
const global = document.getElementById("cbi-<%=appname%>-global");
|
||||
const global = document.getElementById("cbi-<%=appname%>-" + global_id);
|
||||
if (global) {
|
||||
// 分流规则节点提前加入 “编辑” 占位符,以保证节点列表左对齐
|
||||
document.querySelectorAll('.td[data-widget="nodes_listvalue"][data-name="_node"] > div').forEach(container => {
|
||||
@@ -109,10 +112,7 @@ local appname = api.appname
|
||||
|
||||
await delay(100);
|
||||
|
||||
const node = global.getElementsByClassName("cbi-section-node")[0];
|
||||
const node_id = node.getAttribute("id");
|
||||
global_id = node_id;
|
||||
const all_node = node.querySelectorAll("[id]");
|
||||
const all_node = global.querySelectorAll("[id]");
|
||||
const reg1 = /^cbid\..*node\.main$/;
|
||||
//const reg1 = /^cbid\..*\.(tcp_node|udp_node)\.main$/;
|
||||
|
||||
@@ -129,7 +129,7 @@ local appname = api.appname
|
||||
continue;
|
||||
}
|
||||
|
||||
let html = '<a href="#" onclick="return to_edit_node(this);"><%:Edit%></a>';
|
||||
let html = '<a href="#" onclick="return to_edit_node(this, global_id);"><%:Edit%></a>';
|
||||
|
||||
const m = cbid.match(/\.(tcp|udp)_node$/);
|
||||
if (m && (m[1] === "tcp" || m[1] === "udp")) {
|
||||
@@ -149,7 +149,7 @@ local appname = api.appname
|
||||
|
||||
const socks = document.getElementById("cbi-<%=appname%>-socks");
|
||||
if (socks) {
|
||||
const socks_enabled_dom = document.getElementById(global_id + "-socks_enabled");
|
||||
const socks_enabled_dom = document.getElementById("cbi-<%=appname%>-" + global_id + "-socks_enabled");
|
||||
const descr = socks.getElementsByClassName("cbi-section-descr")[0];
|
||||
descr.replaceWith(socks_enabled_dom);
|
||||
const rows = socks.getElementsByClassName("cbi-section-table-row");
|
||||
@@ -164,7 +164,7 @@ local appname = api.appname
|
||||
const node_select = document.getElementById(dom_id);
|
||||
if (!node_select) continue;
|
||||
|
||||
let html = '<a href="#" onclick="return to_edit_node(this);"><%:Edit%></a>';
|
||||
let html = '<a href="#" onclick="return to_edit_node(this, \'socks\');"><%:Edit%></a>';
|
||||
html += '<a href="#" onclick="window.open(\'' + '<%=api.url("get_socks_log")%>?name=' + id.replace("cbi-<%=appname%>-", "") + '\', \'_blank\')"><%:Log%></a>';
|
||||
|
||||
node_select.insertAdjacentHTML("afterend",
|
||||
@@ -249,7 +249,7 @@ local appname = api.appname
|
||||
})();
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => setTimeout(() => {
|
||||
const hiddenSelect = document.getElementById("cbid.<%=appname%>.<%=self.global_cfgid%>.tcp_node");
|
||||
const hiddenSelect = document.getElementById("cbid.<%=appname%>.<%=sid%>.tcp_node");
|
||||
let o_val = hiddenSelect.value
|
||||
const o_hasItem = shunt_list.find(element => element.id == o_val);
|
||||
hiddenSelect.addEventListener("change", function(el){
|
||||
@@ -257,7 +257,7 @@ local appname = api.appname
|
||||
const new_hasItem = shunt_list.find(element => element.id == new_val);
|
||||
if (new_hasItem) {
|
||||
XHR.get('<%=api.url("update_config")%>', {
|
||||
id: "<%=self.global_cfgid%>",
|
||||
id: "<%=sid%>",
|
||||
data: JSON.stringify({
|
||||
tcp_node: new_val
|
||||
})
|
||||
@@ -272,8 +272,8 @@ local appname = api.appname
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
document.getElementById("tab.<%=appname%>.<%=self.global_cfgid%>.Shunt").classList.add('shunt-tab-hidden');
|
||||
document.getElementById("tab.<%=appname%>.<%=self.global_cfgid%>.Shunt").style.display = "none";
|
||||
document.getElementById("tab.<%=appname%>.<%=sid%>.Shunt").classList.add('shunt-tab-hidden');
|
||||
document.getElementById("tab.<%=appname%>.<%=sid%>.Shunt").style.display = "none";
|
||||
} catch (error) {}
|
||||
try {
|
||||
document.querySelector('li[data-tab*="Shunt"]').classList.add('shunt-tab-hidden');
|
||||
@@ -281,7 +281,7 @@ local appname = api.appname
|
||||
} catch (error) {}
|
||||
}
|
||||
});
|
||||
let shunt_taboption = document.getElementById("container.<%=appname%>.<%=self.global_cfgid%>.Shunt");
|
||||
let shunt_taboption = document.getElementById("container.<%=appname%>.<%=sid%>.Shunt");
|
||||
if (shunt_taboption) {
|
||||
let shunt_option_list = document.getElementById("cbi-<%=appname%>-shunt_option_list");
|
||||
if (shunt_option_list) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = api.appname
|
||||
local map = self.map
|
||||
local appname = map.config
|
||||
-%>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local haproxy_enable = api.uci_get_type("global_haproxy", "balancing_enable", "0")
|
||||
local console_port = api.uci_get_type("global_haproxy", "console_port", "")
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local haproxy_enable = map:get("@global_haproxy[0]", "balancing_enable") or "0"
|
||||
local console_port = map:get("@global_haproxy[0]", "console_port") or ""
|
||||
-%>
|
||||
<p id="_status"></p>
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
<%
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local config = map.config
|
||||
local id = self.id
|
||||
local s_cfgid = self.s_cfgid
|
||||
-%>
|
||||
<style>
|
||||
.hidden {
|
||||
display: none !important;
|
||||
@@ -54,15 +61,15 @@
|
||||
}
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
waitForElement('select[name*="<%=self.config%>"][name*="shunt_group"]', function(el) {
|
||||
waitForElement('select[name*="<%=config%>"][name*="shunt_group"]', function(el) {
|
||||
let o_val = el.value;
|
||||
el.addEventListener("change", () => {
|
||||
el.blur();
|
||||
if (o_val != el.value) {
|
||||
let save = true;
|
||||
if (save) {
|
||||
update_config("<%=self.id%>", {
|
||||
shunt_group: getOption("<%=self.config%>", "<%=self.s_cfgid%>", "shunt_group").value,
|
||||
update_config("<%=id%>", {
|
||||
shunt_group: getOption("<%=config%>", "<%=s_cfgid%>", "shunt_group").value,
|
||||
}, get_current_url());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
<%
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local sid = self.section
|
||||
local config = map.config
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
let node_id = "<%=self.section%>";
|
||||
let node_config_url = '<%=self.api.url("node_config")%>/' + node_id;
|
||||
let node_id = "<%=sid%>";
|
||||
let node_config_url = '<%=api.url("node_config")%>/' + node_id;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
waitForElement('select[name*="<%=self.config%>"][name*="type"]', function(el) {
|
||||
waitForElement('select[name*="<%=config%>"][name*="type"]', function(el) {
|
||||
let o_val = el.value;
|
||||
el.addEventListener("change", () => {
|
||||
el.blur();
|
||||
@@ -18,16 +24,16 @@
|
||||
}
|
||||
*/
|
||||
update_config(node_id, {
|
||||
remarks: getOption("<%=self.config%>", "<%=self.section%>", "remarks").value,
|
||||
group: getOption("<%=self.config%>", "<%=self.section%>", "group").value,
|
||||
type: getOption("<%=self.config%>", "<%=self.section%>", "type").value,
|
||||
remarks: getOption("<%=config%>", "<%=sid%>", "remarks").value,
|
||||
group: getOption("<%=config%>", "<%=sid%>", "group").value,
|
||||
type: getOption("<%=config%>", "<%=sid%>", "type").value,
|
||||
//protocol: ''
|
||||
}, node_config_url);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
waitForElement('select[name*="<%=self.config%>"][name*="protocol"]', function(el) {
|
||||
waitForElement('select[name*="<%=config%>"][name*="protocol"]', function(el) {
|
||||
let o_val = el.value;
|
||||
el.addEventListener("change", () => {
|
||||
el.blur();
|
||||
@@ -43,9 +49,9 @@
|
||||
}
|
||||
*/
|
||||
update_config(node_id, {
|
||||
remarks: getOption("<%=self.config%>", "<%=self.section%>", "remarks").value,
|
||||
group: getOption("<%=self.config%>", "<%=self.section%>", "group").value,
|
||||
protocol: getOption("<%=self.config%>", "<%=self.section%>", name).value,
|
||||
remarks: getOption("<%=config%>", "<%=sid%>", "remarks").value,
|
||||
group: getOption("<%=config%>", "<%=sid%>", "group").value,
|
||||
protocol: getOption("<%=config%>", "<%=sid%>", name).value,
|
||||
}, node_config_url);
|
||||
} else {
|
||||
window.location.href = node_config_url + "?select_proto=" + encodeURIComponent(el.value);
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<%
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local sid = self.section
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function fetchCertSha256(el) {
|
||||
@@ -5,7 +10,7 @@
|
||||
el.setAttribute("data-loading", "1");
|
||||
el.style.pointerEvents = "none";
|
||||
el.style.color = "red";
|
||||
XHR.get('<%=self.api.url("fetch_certsha256")%>', { id: "<%=self.section%>" }, function(x, res) {
|
||||
XHR.get('<%=api.url("fetch_certsha256")%>', { id: "<%=sid%>" }, function(x, res) {
|
||||
el.setAttribute("data-loading", "0");
|
||||
el.style.pointerEvents = "";
|
||||
el.style.color = "";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<%
|
||||
local api = self.api
|
||||
local appname = api.appname
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local appname = map.config
|
||||
local is_js_luci = api.is_js_luci()
|
||||
local section_tag = is_js_luci and "div" or "fieldset"
|
||||
-%>
|
||||
@@ -415,8 +415,8 @@ table td, .table .td {
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
let auto_detection_time = "<%=api.uci_get_type("global_other", "auto_detection_time", "0")%>"
|
||||
let show_node_info = "<%=api.uci_get_type("global_other", "show_node_info", "0")%>"
|
||||
let auto_detection_time = "<%=map:get("@global_other[0]", "auto_detection_time") or "0"%>"
|
||||
let show_node_info = "<%=map:get("@global_other[0]", "show_node_info") or "0"%>"
|
||||
|
||||
var ajax = {
|
||||
list: [],
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local fs = api.fs
|
||||
local has_old_geoip = fs.access("/tmp/bak_v2ray/geoip.dat")
|
||||
local has_old_geosite = fs.access("/tmp/bak_v2ray/geosite.dat")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<%
|
||||
local api = self.api
|
||||
local appname = api.appname
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local appname = map.config
|
||||
local is_js_luci = api.is_js_luci()
|
||||
local section_tag = is_js_luci and "div" or "fieldset"
|
||||
local title_tag = is_js_luci and "h3" or "legend"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local translate = luci.i18n.translate
|
||||
local total_lines_text = translate("Total Lines")
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
@@ -14,7 +13,7 @@ local total_lines_text = translate("Total Lines")
|
||||
textarea.innerHTML = data;
|
||||
//textarea.scrollTop = textarea.scrollHeight;
|
||||
var totalLinesLabel = document.getElementById('gfw_total_lines');
|
||||
totalLinesLabel.innerHTML = "<%= total_lines_text %> " + total_lines;
|
||||
totalLinesLabel.innerHTML = "<%:Total Lines%> " + total_lines;
|
||||
})
|
||||
}
|
||||
|
||||
@@ -27,7 +26,7 @@ local total_lines_text = translate("Total Lines")
|
||||
textarea.innerHTML = data;
|
||||
//textarea.scrollTop = textarea.scrollHeight;
|
||||
var totalLinesLabel = document.getElementById('chn_total_lines');
|
||||
totalLinesLabel.innerHTML = "<%= total_lines_text %> " + total_lines;
|
||||
totalLinesLabel.innerHTML = "<%:Total Lines%> " + total_lines;
|
||||
})
|
||||
}
|
||||
|
||||
@@ -40,7 +39,7 @@ local total_lines_text = translate("Total Lines")
|
||||
textarea.innerHTML = data;
|
||||
//textarea.scrollTop = textarea.scrollHeight;
|
||||
var totalLinesLabel = document.getElementById('chnroute_total_lines');
|
||||
totalLinesLabel.innerHTML = "<%= total_lines_text %> " + total_lines;
|
||||
totalLinesLabel.innerHTML = "<%:Total Lines%> " + total_lines;
|
||||
})
|
||||
}
|
||||
//]]>
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
<%
|
||||
local api = self.api
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local config = map.config
|
||||
local section = self.section
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
let node_id = "<%=self.section%>";
|
||||
let node_id = "<%=section%>";
|
||||
let node_config_url = '<%=api.url("server_config")%>/' + node_id;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
waitForElement('select[name*="<%=self.config%>"][name*="type"]', function(el) {
|
||||
waitForElement('select[name*="<%=config%>"][name*="type"]', function(el) {
|
||||
let o_val = el.value;
|
||||
el.addEventListener("change", () => {
|
||||
el.blur();
|
||||
@@ -16,9 +19,9 @@ local api = self.api
|
||||
if (save) {
|
||||
//document.getElementsByClassName('cbi-button-save')[0].click();
|
||||
server_update_config(node_id, {
|
||||
enable: getOption("<%=self.config%>", node_id, "enable").value,
|
||||
remarks: getOption("<%=self.config%>", node_id, "remarks").value,
|
||||
type: getOption("<%=self.config%>", node_id, "type").value,
|
||||
enable: getOption("<%=config%>", node_id, "enable").value,
|
||||
remarks: getOption("<%=config%>", node_id, "remarks").value,
|
||||
type: getOption("<%=config%>", node_id, "type").value,
|
||||
protocol: ''
|
||||
}, node_config_url);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
<%
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local section = self.section
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function server_update_config(cfgid, data, redirect_url) {
|
||||
XHR.get('<%=self.api.url("server_update_config")%>', {
|
||||
XHR.get('<%=api.url("server_update_config")%>', {
|
||||
id: cfgid,
|
||||
data: JSON.stringify(data)
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<%
|
||||
local api = self.api
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local config = map.config
|
||||
local sectiontype = self.sectiontype
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
@@ -19,7 +22,7 @@ local api = self.api
|
||||
);
|
||||
}
|
||||
|
||||
var edit_btn = document.getElementById("cbi-<%=self.appname%>-<%=self.sectiontype%>").getElementsByClassName("cbi-button cbi-button-edit");
|
||||
var edit_btn = document.getElementById("cbi-<%=config%>-<%=sectiontype%>").getElementsByClassName("cbi-button cbi-button-edit");
|
||||
for (var i = 0; i < edit_btn.length; i++) {
|
||||
try {
|
||||
var onclick_str = edit_btn[i].getAttribute("onclick");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
@@ -1508,18 +1508,6 @@ msgstr "配合伪装类型 DNS 使用,可随便填一个域名。"
|
||||
msgid "Auth"
|
||||
msgstr "身份认证"
|
||||
|
||||
msgid "Socks for authentication"
|
||||
msgstr "Socks 认证方式"
|
||||
|
||||
msgid "Socks protocol authentication, support anonymous and password."
|
||||
msgstr "Socks 协议的认证方式,支持匿名方式和账号密码方式。"
|
||||
|
||||
msgid "anonymous"
|
||||
msgstr "匿名"
|
||||
|
||||
msgid "User Password"
|
||||
msgstr "账号密码"
|
||||
|
||||
msgid "This username already exists."
|
||||
msgstr "该用户名已存在。"
|
||||
|
||||
@@ -1538,18 +1526,6 @@ msgstr "IPv6 透明代理(TProxy)"
|
||||
msgid "Experimental feature. Make sure that your node supports IPv6."
|
||||
msgstr "实验特性,请确保你的节点支持IPv6"
|
||||
|
||||
msgid "Status info"
|
||||
msgstr "状态信息"
|
||||
|
||||
msgid "Big icon"
|
||||
msgstr "大图标"
|
||||
|
||||
msgid "Show node check"
|
||||
msgstr "显示节点检测"
|
||||
|
||||
msgid "Show Show IP111"
|
||||
msgstr "显示 IP111"
|
||||
|
||||
msgid "Destination protocol"
|
||||
msgstr "目标协议"
|
||||
|
||||
|
||||
@@ -5,9 +5,6 @@ if [ -e "/etc/config/ucitrack" ]; then
|
||||
delete ucitrack.@passwall[-1]
|
||||
add ucitrack passwall
|
||||
set ucitrack.@passwall[-1].init=passwall
|
||||
delete ucitrack.@passwall_server[-1]
|
||||
add ucitrack passwall_server
|
||||
set ucitrack.@passwall_server[-1].init=passwall_server
|
||||
commit ucitrack
|
||||
EOF
|
||||
fi
|
||||
@@ -18,11 +15,6 @@ uci -q batch <<-EOF
|
||||
set firewall.passwall.type='script'
|
||||
set firewall.passwall.path='/var/etc/passwall.include'
|
||||
|
||||
delete firewall.passwall_server
|
||||
set firewall.passwall_server=include
|
||||
set firewall.passwall_server.type='script'
|
||||
set firewall.passwall_server.path='/var/etc/passwall_server.include'
|
||||
|
||||
set dhcp.@dnsmasq[0].localuse=1
|
||||
commit dhcp
|
||||
set uhttpd.main.max_requests=50
|
||||
@@ -31,12 +23,9 @@ EOF
|
||||
|
||||
if [ -x "/sbin/fw3" ]; then
|
||||
uci -q set firewall.passwall.reload='1'
|
||||
uci -q set firewall.passwall_server.reload='1'
|
||||
else
|
||||
uci -q delete firewall.passwall.reload
|
||||
uci -q delete firewall.passwall.fw4_compatible
|
||||
uci -q delete firewall.passwall_server.reload
|
||||
uci -q delete firewall.passwall_server.fw4_compatible
|
||||
fi
|
||||
uci commit firewall
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -e "/etc/config/ucitrack" ]; then
|
||||
uci -q batch <<-EOF
|
||||
delete ucitrack.@passwall_server[-1]
|
||||
add ucitrack passwall_server
|
||||
set ucitrack.@passwall_server[-1].init=passwall_server
|
||||
commit ucitrack
|
||||
EOF
|
||||
fi
|
||||
|
||||
uci -q batch <<-EOF
|
||||
delete firewall.passwall_server
|
||||
set firewall.passwall_server=include
|
||||
set firewall.passwall_server.type='script'
|
||||
set firewall.passwall_server.path='/var/etc/passwall_server.include'
|
||||
EOF
|
||||
|
||||
if [ -x "/sbin/fw3" ]; then
|
||||
uci -q set firewall.passwall_server.reload='1'
|
||||
else
|
||||
uci -q delete firewall.passwall_server.reload
|
||||
uci -q delete firewall.passwall_server.fw4_compatible
|
||||
fi
|
||||
uci commit firewall
|
||||
|
||||
rm -f /tmp/luci-indexcache /tmp/luci-indexcache.*
|
||||
rm -rf /tmp/luci-modulecache/
|
||||
killall -HUP rpcd 2>/dev/null
|
||||
|
||||
exit 0
|
||||
@@ -23,11 +23,11 @@ local haproxy_conf = var["-conf"]
|
||||
local haproxy_dns = var["-dns"] or "119.29.29.29:53,223.5.5.5:53"
|
||||
|
||||
local cpu_thread = sys.exec('echo -n $(cat /proc/cpuinfo | grep "processor" | wc -l)') or "1"
|
||||
local health_check_type = uci:get(appname, "@global_haproxy[0]", "health_check_type") or "tcp"
|
||||
local health_check_inter = uci:get(appname, "@global_haproxy[0]", "health_check_inter") or "20"
|
||||
local balancingStrategy = uci:get(appname, "@global_haproxy[0]", "balancingStrategy") or "roundrobin"
|
||||
local console_port = uci:get(appname, "@global_haproxy[0]", "console_port")
|
||||
local bind_local = uci:get(appname, "@global_haproxy[0]", "bind_local") or "0"
|
||||
local health_check_type = uci:get(api.c_config, "@global_haproxy[0]", "health_check_type") or "tcp"
|
||||
local health_check_inter = uci:get(api.c_config, "@global_haproxy[0]", "health_check_inter") or "20"
|
||||
local balancingStrategy = uci:get(api.c_config, "@global_haproxy[0]", "balancingStrategy") or "roundrobin"
|
||||
local console_port = uci:get(api.c_config, "@global_haproxy[0]", "console_port")
|
||||
local bind_local = uci:get(api.c_config, "@global_haproxy[0]", "bind_local") or "0"
|
||||
local bind_address = "0.0.0.0"
|
||||
if bind_local == "1" then bind_address = "127.0.0.1" end
|
||||
|
||||
@@ -94,15 +94,15 @@ f_out:write(haproxy_config)
|
||||
|
||||
local listens = {}
|
||||
|
||||
uci:foreach(appname, "haproxy_config", function(t)
|
||||
uci:foreach(api.c_config, "haproxy_config", function(t)
|
||||
if t.enabled == "1" then
|
||||
local server_remark
|
||||
local server_address
|
||||
local server_port
|
||||
local lbss = t.lbss
|
||||
local listen_port = tonumber(t.haproxy_port) or 0
|
||||
local server_node = uci:get_all(appname, lbss)
|
||||
local hop = (health_check_type == "passwall_logic") and (server_node.hysteria_hop or server_node.hysteria2_hop) or nil
|
||||
local server_node = uci:get_all(api.c_config, lbss)
|
||||
local hop = (health_check_type == "script_logic") and (server_node.hysteria_hop or server_node.hysteria2_hop) or nil
|
||||
hop = hop and hop:gsub(":", "-") or nil
|
||||
if server_node and server_node.address and (server_node.port or hop) then
|
||||
server_remark = server_node.address .. ":" .. (server_node.port or hop)
|
||||
@@ -110,7 +110,7 @@ uci:foreach(appname, "haproxy_config", function(t)
|
||||
server_port = server_node.port or hop
|
||||
t.origin_address = server_address
|
||||
t.origin_port = server_port
|
||||
if health_check_type == "passwall_logic" then
|
||||
if health_check_type == "script_logic" then
|
||||
if server_node.type ~= "Socks" then
|
||||
local relay_port = server_node.port
|
||||
local new_port = api.get_new_port()
|
||||
@@ -172,7 +172,7 @@ listen %s
|
||||
balance %s
|
||||
]], port, bind_address, port, balancingStrategy))
|
||||
|
||||
if health_check_type == "passwall_logic" then
|
||||
if health_check_type == "script_logic" then
|
||||
f_out:write(string.format([[
|
||||
option external-check
|
||||
external-check command "/usr/share/%s/haproxy_check.sh"
|
||||
@@ -214,8 +214,8 @@ listen %s
|
||||
end
|
||||
|
||||
--控制台配置
|
||||
local console_user = uci:get(appname, "@global_haproxy[0]", "console_user")
|
||||
local console_password = uci:get(appname, "@global_haproxy[0]", "console_password")
|
||||
local console_user = uci:get(api.c_config, "@global_haproxy[0]", "console_user")
|
||||
local console_password = uci:get(api.c_config, "@global_haproxy[0]", "console_password")
|
||||
local str = [[
|
||||
listen console
|
||||
bind 0.0.0.0:%s
|
||||
@@ -230,8 +230,8 @@ f_out:write("\n" .. string.format(str, console_port, (console_user and console_u
|
||||
f_out:close()
|
||||
|
||||
--passwall内置健康检查URL
|
||||
if health_check_type == "passwall_logic" then
|
||||
local probeUrl = uci:get(appname, "@global_haproxy[0]", "health_probe_url") or "https://www.google.com/generate_204"
|
||||
if health_check_type == "script_logic" then
|
||||
local probeUrl = uci:get(api.c_config, "@global_haproxy[0]", "health_probe_url") or "https://www.google.com/generate_204"
|
||||
local f_url = io.open(haproxy_path .. "/Probe_URL", "w")
|
||||
f_url:write(probeUrl)
|
||||
f_url:close()
|
||||
|
||||
@@ -31,8 +31,8 @@ local RULES_PATH = "/usr/share/" .. appname .. "/rules"
|
||||
local FLAG_PATH = TMP_ACL_PATH .. "/" .. FLAG
|
||||
local config_lines = {}
|
||||
local tmp_lines = {}
|
||||
local USE_GEOVIEW = uci:get(appname, "@global_rules[0]", "enable_geoview")
|
||||
local IS_SHUNT_NODE = uci:get(appname, TCP_NODE, "protocol") == "_shunt"
|
||||
local USE_GEOVIEW = uci:get(api.c_config, "@global_rules[0]", "enable_geoview")
|
||||
local IS_SHUNT_NODE = uci:get(api.c_config, TCP_NODE, "protocol") == "_shunt"
|
||||
|
||||
if not api.is_finded("geoview") then
|
||||
USE_GEOVIEW = "0"
|
||||
@@ -92,7 +92,7 @@ local function insert_array_after(array1, array2, target) --将array2插入到ar
|
||||
end
|
||||
|
||||
local function get_geosite(list_arg, out_path)
|
||||
local geosite_path = uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
|
||||
local geosite_path = uci:get(api.c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
|
||||
geosite_path = geosite_path:match("^(.*)/") .. "/geosite.dat"
|
||||
if not is_file_nonzero(geosite_path) then return 1 end
|
||||
local bin = api.finded_com("geoview")
|
||||
@@ -183,7 +183,7 @@ if not is_file_nonzero(file_vpslist) then
|
||||
written_domains[address] = true
|
||||
end
|
||||
end
|
||||
uci:foreach(appname, "nodes", function(t)
|
||||
uci:foreach(api.c_config, "nodes", function(t)
|
||||
process_address(t.address)
|
||||
process_address(t.download_address)
|
||||
local dns, _ = api.get_domain_port_from_url(t.domain_resolver_dns or t.domain_resolver_dns_https or "")
|
||||
@@ -191,7 +191,7 @@ if not is_file_nonzero(file_vpslist) then
|
||||
process_address(dns)
|
||||
end
|
||||
end)
|
||||
uci:foreach(appname, "subscribe_list", function(t) --订阅链接
|
||||
uci:foreach(api.c_config, "subscribe_list", function(t) --订阅链接
|
||||
local url, _ = api.get_domain_port_from_url(t.url or "")
|
||||
if url and url ~= "" then
|
||||
process_address(url)
|
||||
@@ -387,9 +387,9 @@ if IS_SHUNT_NODE then
|
||||
local file_shunt_host = FLAG_PATH .. "/shunt_proxy_host"
|
||||
local geosite_white_arg, geosite_shunt_arg = "", ""
|
||||
|
||||
local t = uci:get_all(appname, TCP_NODE)
|
||||
local t = uci:get_all(api.c_config, TCP_NODE)
|
||||
local default_node_id = t["default_node"] or "_direct"
|
||||
uci:foreach(appname, "shunt_rules", function(s)
|
||||
uci:foreach(api.c_config, "shunt_rules", function(s)
|
||||
local _node_id = t[s[".name"]]
|
||||
if _node_id and _node_id ~= "_blackhole" and t["shunt_group"] == s.group then
|
||||
if _node_id == "_default" then
|
||||
|
||||
@@ -24,8 +24,8 @@ end
|
||||
local function backup_servers()
|
||||
local DNSMASQ_DNS = uci:get("dhcp", "@dnsmasq[0]", "server")
|
||||
if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then
|
||||
uci:set(appname, "@global[0]", "dnsmasq_servers", DNSMASQ_DNS)
|
||||
api.uci_save(uci, appname, true)
|
||||
uci:set(api.c_config, "@global[0]", "dnsmasq_servers", DNSMASQ_DNS)
|
||||
api.uci_save(uci, api.c_config, true)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,13 +37,13 @@ local function restore_servers()
|
||||
tinsert(dns_table, v)
|
||||
end
|
||||
end
|
||||
local OLD_SERVER = uci:get(appname, "@global[0]", "dnsmasq_servers")
|
||||
local OLD_SERVER = uci:get(api.c_config, "@global[0]", "dnsmasq_servers")
|
||||
if OLD_SERVER and #OLD_SERVER > 0 then
|
||||
for k, v in ipairs(OLD_SERVER) do
|
||||
tinsert(dns_table, v)
|
||||
end
|
||||
uci:delete(appname, "@global[0]", "dnsmasq_servers")
|
||||
api.uci_save(uci, appname, true)
|
||||
uci:delete(api.c_config, "@global[0]", "dnsmasq_servers")
|
||||
api.uci_save(uci, api.c_config, true)
|
||||
end
|
||||
if dns_table and #dns_table > 0 then
|
||||
uci:set_list("dhcp", "@dnsmasq[0]", "server", dns_table)
|
||||
@@ -180,8 +180,8 @@ function add_rule(var)
|
||||
local CACHE_DNS_PATH = CACHE_PATH .. "/" .. CACHE_FLAG
|
||||
local CACHE_TEXT_FILE = CACHE_DNS_PATH .. ".txt"
|
||||
local USE_CHINADNS_NG = "0"
|
||||
local IS_SHUNT_NODE = uci:get(appname, TCP_NODE, "protocol") == "_shunt"
|
||||
local USE_GEOVIEW = uci:get(appname, "@global_rules[0]", "enable_geoview")
|
||||
local IS_SHUNT_NODE = uci:get(api.c_config, TCP_NODE, "protocol") == "_shunt"
|
||||
local USE_GEOVIEW = uci:get(api.c_config, "@global_rules[0]", "enable_geoview")
|
||||
|
||||
local list1 = {}
|
||||
local excluded_domain = {}
|
||||
@@ -307,7 +307,7 @@ function add_rule(var)
|
||||
end
|
||||
|
||||
local function foreach_geosite(list_arg, callback)
|
||||
local geosite_path = uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
|
||||
local geosite_path = uci:get(api.c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
|
||||
geosite_path = geosite_path:match("^(.*)/") .. "/geosite.dat"
|
||||
if not fs.access(geosite_path) then return end
|
||||
local bin = api.finded_com("geoview")
|
||||
@@ -412,7 +412,7 @@ function add_rule(var)
|
||||
set_domain_ipset(address, table.concat(sets, ","))
|
||||
end
|
||||
end
|
||||
uci:foreach(appname, "nodes", function(t)
|
||||
uci:foreach(api.c_config, "nodes", function(t)
|
||||
process_address(t.address)
|
||||
process_address(t.download_address)
|
||||
local dns, _ = api.get_domain_port_from_url(t.domain_resolver_dns or t.domain_resolver_dns_https or "")
|
||||
@@ -420,7 +420,7 @@ function add_rule(var)
|
||||
process_address(dns)
|
||||
end
|
||||
end)
|
||||
uci:foreach(appname, "subscribe_list", function(t) --订阅链接
|
||||
uci:foreach(api.c_config, "subscribe_list", function(t) --订阅链接
|
||||
local url, _ = api.get_domain_port_from_url(t.url or "")
|
||||
if url and url ~= "" then
|
||||
process_address(url)
|
||||
@@ -615,9 +615,9 @@ function add_rule(var)
|
||||
|
||||
--分流规则
|
||||
if IS_SHUNT_NODE and USE_CHINADNS_NG == "0" then
|
||||
local t = uci:get_all(appname, TCP_NODE)
|
||||
local t = uci:get_all(api.c_config, TCP_NODE)
|
||||
local default_node_id = t["default_node"] or "_direct"
|
||||
uci:foreach(appname, "shunt_rules", function(s)
|
||||
uci:foreach(api.c_config, "shunt_rules", function(s)
|
||||
local _node_id = t[s[".name"]]
|
||||
if _node_id and _node_id ~= "_blackhole" and t["shunt_group"] == s.group then
|
||||
if _node_id == "_default" then
|
||||
|
||||
@@ -37,8 +37,8 @@ local FLAG_PATH = TMP_ACL_PATH .. "/" .. FLAG
|
||||
local TMP_CONF_FILE = FLAG_PATH .. "/smartdns.conf"
|
||||
local config_lines = {}
|
||||
local tmp_lines = {}
|
||||
local USE_GEOVIEW = uci:get(appname, "@global_rules[0]", "enable_geoview")
|
||||
local IS_SHUNT_NODE = uci:get(appname, TCP_NODE, "protocol") == "_shunt"
|
||||
local USE_GEOVIEW = uci:get(api.c_config, "@global_rules[0]", "enable_geoview")
|
||||
local IS_SHUNT_NODE = uci:get(api.c_config, TCP_NODE, "protocol") == "_shunt"
|
||||
|
||||
if not api.is_finded("geoview") then
|
||||
USE_GEOVIEW = "0"
|
||||
@@ -98,7 +98,7 @@ local function insert_array_after(array1, array2, target) --将array2插入到ar
|
||||
end
|
||||
|
||||
local function get_geosite(list_arg, out_path)
|
||||
local geosite_path = uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
|
||||
local geosite_path = uci:get(api.c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
|
||||
geosite_path = geosite_path:match("^(.*)/") .. "/geosite.dat"
|
||||
if not is_file_nonzero(geosite_path) then return 1 end
|
||||
local bin = api.finded_com("geoview")
|
||||
@@ -187,7 +187,7 @@ if not REMOTE_GROUP or REMOTE_GROUP == "nil" then
|
||||
sys.call('sed -i "/passwall/d" /etc/smartdns/custom.conf >/dev/null 2>&1')
|
||||
end
|
||||
|
||||
local force_https_soa = uci:get(appname, "@global[0]", "force_https_soa") or 0
|
||||
local force_https_soa = uci:get(api.c_config, "@global[0]", "force_https_soa") or 0
|
||||
local proxy_server_name = "passwall-proxy-server"
|
||||
config_lines = {
|
||||
tonumber(LISTEN_PORT) ~= 0 and "bind [::]:" .. LISTEN_PORT .. "@lo" or "",
|
||||
@@ -342,7 +342,7 @@ if not is_file_nonzero(file_vpslist) then
|
||||
written_domains[address] = true
|
||||
end
|
||||
end
|
||||
uci:foreach(appname, "nodes", function(t)
|
||||
uci:foreach(api.c_config, "nodes", function(t)
|
||||
process_address(t.address)
|
||||
process_address(t.download_address)
|
||||
local dns, _ = api.get_domain_port_from_url(t.domain_resolver_dns or t.domain_resolver_dns_https or "")
|
||||
@@ -350,7 +350,7 @@ if not is_file_nonzero(file_vpslist) then
|
||||
process_address(dns)
|
||||
end
|
||||
end)
|
||||
uci:foreach(appname, "subscribe_list", function(t) --订阅链接
|
||||
uci:foreach(api.c_config, "subscribe_list", function(t) --订阅链接
|
||||
local url, _ = api.get_domain_port_from_url(t.url or "")
|
||||
if url and url ~= "" then
|
||||
process_address(url)
|
||||
@@ -555,9 +555,9 @@ if IS_SHUNT_NODE then
|
||||
local file_shunt_host = FLAG_PATH .. "/shunt_proxy_host"
|
||||
local geosite_white_arg, geosite_shunt_arg = "", ""
|
||||
|
||||
local t = uci:get_all(appname, TCP_NODE)
|
||||
local t = uci:get_all(api.c_config, TCP_NODE)
|
||||
local default_node_id = t["default_node"] or "_direct"
|
||||
uci:foreach(appname, "shunt_rules", function(s)
|
||||
uci:foreach(api.c_config, "shunt_rules", function(s)
|
||||
local _node_id = t[s[".name"]]
|
||||
if _node_id and _node_id ~= "_blackhole" and t["shunt_group"] == s.group then
|
||||
if _node_id == "_default" then
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
local api = require ("luci.passwall.api")
|
||||
local name = api.appname
|
||||
local c_config = api.c_config
|
||||
local uci = api.uci
|
||||
local sys = api.sys
|
||||
local jsonc = api.jsonc
|
||||
@@ -23,14 +24,14 @@ local geosite_update = "0"
|
||||
|
||||
local excluded_domain = {"apple.com","sina.cn","sina.com.cn","baidu.com","byr.cn","jlike.com","weibo.com","zhongsou.com","youdao.com","sogou.com","so.com","soso.com","aliyun.com","taobao.com","jd.com","qq.com","bing.com"}
|
||||
|
||||
local gfwlist_url = uci:get(name, "@global_rules[0]", "gfwlist_url") or {"https://fastly.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/gfw.txt"}
|
||||
local chnroute_url = uci:get(name, "@global_rules[0]", "chnroute_url") or {"https://ispip.clang.cn/all_cn.txt"}
|
||||
local chnroute6_url = uci:get(name, "@global_rules[0]", "chnroute6_url") or {"https://ispip.clang.cn/all_cn_ipv6.txt"}
|
||||
local chnlist_url = uci:get(name, "@global_rules[0]", "chnlist_url") or {"https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/accelerated-domains.china.conf","https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/apple.china.conf","https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/google.china.conf"}
|
||||
local geoip_url = uci:get(name, "@global_rules[0]", "geoip_url") or "https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat"
|
||||
local geosite_url = uci:get(name, "@global_rules[0]", "geosite_url") or "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
|
||||
local asset_location = uci:get(name, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
|
||||
local geo2rule = uci:get(name, "@global_rules[0]", "geo2rule") or "0"
|
||||
local gfwlist_url = uci:get(c_config, "@global_rules[0]", "gfwlist_url") or {"https://fastly.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/gfw.txt"}
|
||||
local chnroute_url = uci:get(c_config, "@global_rules[0]", "chnroute_url") or {"https://ispip.clang.cn/all_cn.txt"}
|
||||
local chnroute6_url = uci:get(c_config, "@global_rules[0]", "chnroute6_url") or {"https://ispip.clang.cn/all_cn_ipv6.txt"}
|
||||
local chnlist_url = uci:get(c_config, "@global_rules[0]", "chnlist_url") or {"https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/accelerated-domains.china.conf","https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/apple.china.conf","https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/google.china.conf"}
|
||||
local geoip_url = uci:get(c_config, "@global_rules[0]", "geoip_url") or "https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat"
|
||||
local geosite_url = uci:get(c_config, "@global_rules[0]", "geosite_url") or "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
|
||||
local asset_location = uci:get(c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
|
||||
local geo2rule = uci:get(c_config, "@global_rules[0]", "geo2rule") or "0"
|
||||
local geoip_update_ok, geosite_update_ok = false, false
|
||||
asset_location = asset_location:match("/$") and asset_location or (asset_location .. "/")
|
||||
local backup_path = "/tmp/bak_v2ray/"
|
||||
@@ -659,12 +660,12 @@ if arg2 then
|
||||
end)
|
||||
if rollback then arg2 = nil end
|
||||
else
|
||||
gfwlist_update = uci:get(name, "@global_rules[0]", "gfwlist_update") or "1"
|
||||
chnroute_update = uci:get(name, "@global_rules[0]", "chnroute_update") or "1"
|
||||
chnroute6_update = uci:get(name, "@global_rules[0]", "chnroute6_update") or "1"
|
||||
chnlist_update = uci:get(name, "@global_rules[0]", "chnlist_update") or "1"
|
||||
geoip_update = uci:get(name, "@global_rules[0]", "geoip_update") or "1"
|
||||
geosite_update = uci:get(name, "@global_rules[0]", "geosite_update") or "1"
|
||||
gfwlist_update = uci:get(c_config, "@global_rules[0]", "gfwlist_update") or "1"
|
||||
chnroute_update = uci:get(c_config, "@global_rules[0]", "chnroute_update") or "1"
|
||||
chnroute6_update = uci:get(c_config, "@global_rules[0]", "chnroute6_update") or "1"
|
||||
chnlist_update = uci:get(c_config, "@global_rules[0]", "chnlist_update") or "1"
|
||||
geoip_update = uci:get(c_config, "@global_rules[0]", "geoip_update") or "1"
|
||||
geosite_update = uci:get(c_config, "@global_rules[0]", "geosite_update") or "1"
|
||||
end
|
||||
if geo2rule ~= "1" and gfwlist_update == "0" and chnroute_update == "0" and chnroute6_update == "0" and chnlist_update == "0" and geoip_update == "0" and geosite_update == "0" then
|
||||
os.exit(0)
|
||||
@@ -777,13 +778,13 @@ else
|
||||
end
|
||||
|
||||
if not rollback then
|
||||
uci:set(name, "@global_rules[0]", "gfwlist_update", gfwlist_update)
|
||||
uci:set(name, "@global_rules[0]", "chnroute_update", chnroute_update)
|
||||
uci:set(name, "@global_rules[0]", "chnroute6_update", chnroute6_update)
|
||||
uci:set(name, "@global_rules[0]", "chnlist_update", chnlist_update)
|
||||
uci:set(name, "@global_rules[0]", "geoip_update", geoip_update)
|
||||
uci:set(name, "@global_rules[0]", "geosite_update", geosite_update)
|
||||
api.uci_save(uci, name, true)
|
||||
uci:set(c_config, "@global_rules[0]", "gfwlist_update", gfwlist_update)
|
||||
uci:set(c_config, "@global_rules[0]", "chnroute_update", chnroute_update)
|
||||
uci:set(c_config, "@global_rules[0]", "chnroute6_update", chnroute6_update)
|
||||
uci:set(c_config, "@global_rules[0]", "chnlist_update", chnlist_update)
|
||||
uci:set(c_config, "@global_rules[0]", "geoip_update", geoip_update)
|
||||
uci:set(c_config, "@global_rules[0]", "geosite_update", geosite_update)
|
||||
api.uci_save(uci, c_config, true)
|
||||
end
|
||||
|
||||
if reboot == 1 then
|
||||
@@ -794,8 +795,8 @@ if reboot == 1 then
|
||||
end
|
||||
|
||||
log("重启服务,应用新的规则。")
|
||||
uci:set(name, "@global[0]", "flush_set", "1")
|
||||
api.uci_save(uci, name, true, true)
|
||||
uci:set(c_config, "@global[0]", "flush_set", "1")
|
||||
api.uci_save(uci, c_config, true, true)
|
||||
end
|
||||
log("规则更新完毕...\n")
|
||||
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
require 'luci.util'
|
||||
require 'luci.jsonc'
|
||||
require 'luci.sys'
|
||||
local appname = 'passwall'
|
||||
local api = require ("luci.passwall.api")
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = api.appname
|
||||
local c_config = api.c_config
|
||||
local datatypes = require "luci.cbi.datatypes"
|
||||
|
||||
loadfile("/usr/share/" .. appname .. "/clash_subconverter.lua")()
|
||||
@@ -30,9 +31,9 @@ local has_singbox = api.finded_com("sing-box")
|
||||
local has_xray = api.finded_com("xray")
|
||||
local has_hysteria2 = api.finded_com("hysteria")
|
||||
local DEFAULT_ALLOWINSECURE = true
|
||||
local DEFAULT_FILTER_KEYWORD_MODE = uci:get(appname, "@global_subscribe[0]", "filter_keyword_mode") or "0"
|
||||
local DEFAULT_FILTER_KEYWORD_DISCARD_LIST = uci:get(appname, "@global_subscribe[0]", "filter_discard_list") or {}
|
||||
local DEFAULT_FILTER_KEYWORD_KEEP_LIST = uci:get(appname, "@global_subscribe[0]", "filter_keep_list") or {}
|
||||
local DEFAULT_FILTER_KEYWORD_MODE = uci:get(c_config, "@global_subscribe[0]", "filter_keyword_mode") or "0"
|
||||
local DEFAULT_FILTER_KEYWORD_DISCARD_LIST = uci:get(c_config, "@global_subscribe[0]", "filter_discard_list") or {}
|
||||
local DEFAULT_FILTER_KEYWORD_KEEP_LIST = uci:get(c_config, "@global_subscribe[0]", "filter_keep_list") or {}
|
||||
-- 取节点使用core类型(节点订阅页面未设置时,自动取默认)
|
||||
local DEFAULT_SS_TYPE = api.get_core("ss_type", {{has_ss_rust,"shadowsocks-rust"},{has_singbox,"sing-box"},{has_xray,"xray"}})
|
||||
local DEFAULT_TROJAN_TYPE = api.get_core("trojan_type", {{has_singbox,"sing-box"},{has_xray,"xray"}})
|
||||
@@ -141,13 +142,13 @@ do
|
||||
local szType = "@global[0]"
|
||||
local option = protocol .. "_node"
|
||||
|
||||
local node_id = uci:get(appname, szType, option)
|
||||
local node_id = uci:get(c_config, szType, option)
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = true,
|
||||
remarks = name .. "节点",
|
||||
currentNode = node_id and uci:get_all(appname, node_id) or nil,
|
||||
currentNode = node_id and uci:get_all(c_config, node_id) or nil,
|
||||
set = function(o, server)
|
||||
uci:set(appname, szType, option, server)
|
||||
uci:set(c_config, szType, option, server)
|
||||
o.newNodeId = server
|
||||
end
|
||||
}
|
||||
@@ -158,7 +159,7 @@ do
|
||||
if true then
|
||||
local i = 0
|
||||
local option = "node"
|
||||
uci:foreach(appname, "socks", function(t)
|
||||
uci:foreach(c_config, "socks", function(t)
|
||||
i = i + 1
|
||||
local id = t[".name"]
|
||||
local node_id = t[option]
|
||||
@@ -166,14 +167,14 @@ do
|
||||
log = true,
|
||||
id = id,
|
||||
remarks = "Socks节点列表[" .. i .. "]",
|
||||
currentNode = node_id and uci:get_all(appname, node_id) or nil,
|
||||
currentNode = node_id and uci:get_all(c_config, node_id) or nil,
|
||||
set = function(o, server)
|
||||
if not server or server == "" then
|
||||
if #nodes_table > 0 then
|
||||
server = nodes_table[1][".name"]
|
||||
end
|
||||
end
|
||||
uci:set(appname, t[".name"], option, server)
|
||||
uci:set(c_config, t[".name"], option, server)
|
||||
o.newNodeId = server
|
||||
end
|
||||
}
|
||||
@@ -183,7 +184,7 @@ do
|
||||
local newNodes = {}
|
||||
for k, asb_node_id in ipairs(t.autoswitch_backup_node) do
|
||||
if asb_node_id then
|
||||
local currentNode = uci:get_all(appname, asb_node_id) or {}
|
||||
local currentNode = uci:get_all(c_config, asb_node_id) or {}
|
||||
if currentNode[".type"] == "nodes" then
|
||||
currentNodes[#currentNodes + 1] = {
|
||||
log = true,
|
||||
@@ -205,7 +206,7 @@ do
|
||||
set = function(o, newNodes)
|
||||
if o then
|
||||
if not newNodes then newNodes = o.newNodes end
|
||||
uci:set_list(appname, id, "autoswitch_backup_node", newNodes or {})
|
||||
uci:set_list(c_config, id, "autoswitch_backup_node", newNodes or {})
|
||||
end
|
||||
end
|
||||
}
|
||||
@@ -221,25 +222,25 @@ do
|
||||
local ip, port = str:match("^([%d%.]+):(%d+)$")
|
||||
return ip and datatypes.ipaddr(ip) and tonumber(port) and tonumber(port) <= 65535
|
||||
end
|
||||
uci:foreach(appname, "haproxy_config", function(t)
|
||||
uci:foreach(c_config, "haproxy_config", function(t)
|
||||
i = i + 1
|
||||
local node_id = t[option]
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = true,
|
||||
id = t[".name"],
|
||||
remarks = "HAProxy负载均衡节点列表[" .. i .. "]",
|
||||
currentNode = node_id and uci:get_all(appname, node_id) or nil,
|
||||
currentNode = node_id and uci:get_all(c_config, node_id) or nil,
|
||||
set = function(o, server)
|
||||
-- 如果当前 lbss 值不是 ip:port 格式,才进行修改
|
||||
if not is_ip_port(t[option]) then
|
||||
uci:set(appname, t[".name"], option, server)
|
||||
uci:set(c_config, t[".name"], option, server)
|
||||
o.newNodeId = server
|
||||
end
|
||||
end,
|
||||
delete = function(o)
|
||||
-- 如果当前 lbss 值不是 ip:port 格式,才进行删除
|
||||
if not is_ip_port(t[option]) then
|
||||
uci:delete(appname, t[".name"])
|
||||
uci:delete(c_config, t[".name"])
|
||||
end
|
||||
end
|
||||
}
|
||||
@@ -249,7 +250,7 @@ do
|
||||
if true then
|
||||
local i = 0
|
||||
local options = {"tcp", "udp"}
|
||||
uci:foreach(appname, "acl_rule", function(t)
|
||||
uci:foreach(c_config, "acl_rule", function(t)
|
||||
i = i + 1
|
||||
for index, value in ipairs(options) do
|
||||
local option = value .. "_node"
|
||||
@@ -258,9 +259,9 @@ do
|
||||
log = true,
|
||||
id = t[".name"],
|
||||
remarks = "访问控制列表[" .. i .. "]",
|
||||
currentNode = node_id and uci:get_all(appname, node_id) or nil,
|
||||
currentNode = node_id and uci:get_all(c_config, node_id) or nil,
|
||||
set = function(o, server)
|
||||
uci:set(appname, t[".name"], option, server)
|
||||
uci:set(c_config, t[".name"], option, server)
|
||||
o.newNodeId = server
|
||||
end
|
||||
}
|
||||
@@ -268,11 +269,11 @@ do
|
||||
end)
|
||||
end
|
||||
|
||||
uci:foreach(appname, "nodes", function(node)
|
||||
uci:foreach(c_config, "nodes", function(node)
|
||||
local node_id = node[".name"]
|
||||
if node.protocol and node.protocol == '_shunt' then
|
||||
local rules = {}
|
||||
uci:foreach(appname, "shunt_rules", function(e)
|
||||
uci:foreach(c_config, "shunt_rules", function(e)
|
||||
if e[".name"] and e.remarks then
|
||||
table.insert(rules, e)
|
||||
table.insert(rules, {
|
||||
@@ -293,7 +294,7 @@ do
|
||||
for k, e in pairs(rules) do
|
||||
local _node_id = node[e[".name"]] or nil
|
||||
if _node_id then
|
||||
local section = uci:get_all(appname, _node_id) or {}
|
||||
local section = uci:get_all(c_config, _node_id) or {}
|
||||
if section[".type"] == "nodes" then
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = false,
|
||||
@@ -301,7 +302,7 @@ do
|
||||
remarks = "分流" .. e.remarks .. "节点",
|
||||
set = function(o, server)
|
||||
if not server then server = "" end
|
||||
uci:set(appname, node_id, e[".name"], server)
|
||||
uci:set(c_config, node_id, e[".name"], server)
|
||||
o.newNodeId = server
|
||||
end
|
||||
}
|
||||
@@ -318,7 +319,7 @@ do
|
||||
log = true,
|
||||
node = b_node_id,
|
||||
currentNode = (function()
|
||||
local section = uci:get_all(appname, b_node_id) or {}
|
||||
local section = uci:get_all(c_config, b_node_id) or {}
|
||||
if section[".type"] == "socks" then
|
||||
return { Socks = b_node_id }
|
||||
end
|
||||
@@ -340,15 +341,15 @@ do
|
||||
set = function(o, newNodes)
|
||||
if o then
|
||||
if not newNodes then newNodes = o.newNodes end
|
||||
uci:set_list(appname, node_id, "balancing_node", newNodes or {})
|
||||
uci:set_list(c_config, node_id, "balancing_node", newNodes or {})
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
--后备节点
|
||||
local currentNode = uci:get_all(appname, node_id) or nil
|
||||
local currentNode = uci:get_all(c_config, node_id) or nil
|
||||
if currentNode and currentNode.fallback_node then
|
||||
local section = uci:get_all(appname, currentNode.fallback_node) or {}
|
||||
local section = uci:get_all(c_config, currentNode.fallback_node) or {}
|
||||
if section[".type"] == "nodes" then
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = true,
|
||||
@@ -356,11 +357,11 @@ do
|
||||
remarks = "Xray负载均衡节点[" .. node_id .. "]后备节点",
|
||||
currentNode = section,
|
||||
set = function(o, server)
|
||||
uci:set(appname, node_id, "fallback_node", server)
|
||||
uci:set(c_config, node_id, "fallback_node", server)
|
||||
o.newNodeId = server
|
||||
end,
|
||||
delete = function(o)
|
||||
uci:delete(appname, node_id, "fallback_node")
|
||||
uci:delete(c_config, node_id, "fallback_node")
|
||||
end
|
||||
}
|
||||
end
|
||||
@@ -375,7 +376,7 @@ do
|
||||
log = true,
|
||||
node = u_node_id,
|
||||
currentNode = (function()
|
||||
local section = uci:get_all(appname, u_node_id) or {}
|
||||
local section = uci:get_all(c_config, u_node_id) or {}
|
||||
if section[".type"] == "socks" then
|
||||
return { Socks = u_node_id }
|
||||
end
|
||||
@@ -397,47 +398,47 @@ do
|
||||
set = function(o, newNodes)
|
||||
if o then
|
||||
if not newNodes then newNodes = o.newNodes end
|
||||
uci:set_list(appname, node_id, "urltest_node", newNodes or {})
|
||||
uci:set_list(c_config, node_id, "urltest_node", newNodes or {})
|
||||
end
|
||||
end
|
||||
}
|
||||
else
|
||||
--前置代理节点
|
||||
local currentNode = uci:get_all(appname, node_id) or nil
|
||||
local currentNode = uci:get_all(c_config, node_id) or nil
|
||||
if currentNode and currentNode.preproxy_node then
|
||||
local section = uci:get_all(appname, currentNode.preproxy_node) or {}
|
||||
local section = uci:get_all(c_config, currentNode.preproxy_node) or {}
|
||||
if section[".type"] == "nodes" then
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = true,
|
||||
id = node_id,
|
||||
remarks = "节点[" .. node_id .. "]前置代理节点",
|
||||
currentNode = uci:get_all(appname, currentNode.preproxy_node) or nil,
|
||||
currentNode = uci:get_all(c_config, currentNode.preproxy_node) or nil,
|
||||
set = function(o, server)
|
||||
uci:set(appname, node_id, "preproxy_node", server)
|
||||
uci:set(c_config, node_id, "preproxy_node", server)
|
||||
o.newNodeId = server
|
||||
end,
|
||||
delete = function(o)
|
||||
uci:delete(appname, node_id, "preproxy_node")
|
||||
uci:delete(c_config, node_id, "preproxy_node")
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
--落地节点
|
||||
local currentNode = uci:get_all(appname, node_id) or nil
|
||||
local currentNode = uci:get_all(c_config, node_id) or nil
|
||||
if currentNode and currentNode.to_node then
|
||||
local section = uci:get_all(appname, currentNode.to_node) or {}
|
||||
local section = uci:get_all(c_config, currentNode.to_node) or {}
|
||||
if section[".type"] == "nodes" then
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = true,
|
||||
id = node_id,
|
||||
remarks = "节点[" .. node_id .. "]落地节点",
|
||||
currentNode = uci:get_all(appname, currentNode.to_node) or nil,
|
||||
currentNode = uci:get_all(c_config, currentNode.to_node) or nil,
|
||||
set = function(o, server)
|
||||
uci:set(appname, node_id, "to_node", server)
|
||||
uci:set(c_config, node_id, "to_node", server)
|
||||
o.newNodeId = server
|
||||
end,
|
||||
delete = function(o)
|
||||
uci:delete(appname, node_id, "to_node")
|
||||
uci:delete(c_config, node_id, "to_node")
|
||||
end
|
||||
}
|
||||
end
|
||||
@@ -1756,19 +1757,19 @@ local function truncate_nodes(group)
|
||||
end
|
||||
end
|
||||
end
|
||||
uci:foreach(appname, "nodes", function(node)
|
||||
uci:foreach(c_config, "nodes", function(node)
|
||||
if node.add_mode == "2" then
|
||||
if (not group) or (group:lower() == (node.group or ""):lower()) then
|
||||
uci:delete(appname, node['.name'])
|
||||
uci:delete(c_config, node['.name'])
|
||||
end
|
||||
end
|
||||
end)
|
||||
uci:foreach(appname, "subscribe_list", function(o)
|
||||
uci:foreach(c_config, "subscribe_list", function(o)
|
||||
if (not group) or (group:lower() == (o.remark or ""):lower()) then
|
||||
uci:delete(appname, o['.name'], "md5")
|
||||
uci:delete(c_config, o['.name'], "md5")
|
||||
end
|
||||
end)
|
||||
api.uci_save(uci, appname, true)
|
||||
api.uci_save(uci, c_config, true)
|
||||
end
|
||||
|
||||
local function select_node(nodes, config, parentConfig)
|
||||
@@ -1907,10 +1908,10 @@ local function update_node(manual)
|
||||
end
|
||||
|
||||
if manual == 0 and next(group) then
|
||||
uci:foreach(appname, "nodes", function(node)
|
||||
uci:foreach(c_config, "nodes", function(node)
|
||||
-- 如果未发现新节点或手动导入的节点就不要删除了...
|
||||
if node.add_mode == "2" and (node.group and group[node.group:lower()] == true) then
|
||||
uci:delete(appname, node['.name'])
|
||||
uci:delete(c_config, node['.name'])
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -1923,9 +1924,9 @@ local function update_node(manual)
|
||||
-- Subscription Group Chain Agent
|
||||
local function valid_chain_node(node)
|
||||
if not node then return "" end
|
||||
local cp = uci:get(appname, node, "chain_proxy") or ""
|
||||
local am = uci:get(appname, node, "add_mode") or "0"
|
||||
chain_node_type = (cp == "" and am ~= "2") and (uci:get(appname, node, "type") or "") or ""
|
||||
local cp = uci:get(c_config, node, "chain_proxy") or ""
|
||||
local am = uci:get(c_config, node, "add_mode") or "0"
|
||||
chain_node_type = (cp == "" and am ~= "2") and (uci:get(c_config, node, "type") or "") or ""
|
||||
if chain_node_type ~= "Xray" and chain_node_type ~= "sing-box" then
|
||||
chain_node_type = ""
|
||||
return ""
|
||||
@@ -1944,22 +1945,22 @@ local function update_node(manual)
|
||||
chain_node_type = (outbound_iface_group ~= "") and "iface" or chain_node_type
|
||||
end
|
||||
for _, vv in ipairs(list) do
|
||||
local cfgid = uci:section(appname, "nodes", api.gen_random_char())
|
||||
local cfgid = uci:section(c_config, "nodes", api.gen_random_char())
|
||||
for kkk, vvv in pairs(vv) do
|
||||
if type(vvv) == "table" and next(vvv) ~= nil then
|
||||
uci:set_list(appname, cfgid, kkk, vvv)
|
||||
uci:set_list(c_config, cfgid, kkk, vvv)
|
||||
else
|
||||
if kkk ~= "group" or vvv ~= "default" then
|
||||
uci:set(appname, cfgid, kkk, vvv)
|
||||
uci:set(c_config, cfgid, kkk, vvv)
|
||||
end
|
||||
-- sing-box/xray 节点域名解析
|
||||
if kkk == "type" and (vvv == "Xray" or vvv == "sing-box") then
|
||||
if domain_resolver then
|
||||
uci:set(appname, cfgid, "domain_resolver", domain_resolver)
|
||||
uci:set(c_config, cfgid, "domain_resolver", domain_resolver)
|
||||
if domain_resolver_dns then
|
||||
uci:set(appname, cfgid, "domain_resolver_dns", domain_resolver_dns)
|
||||
uci:set(c_config, cfgid, "domain_resolver_dns", domain_resolver_dns)
|
||||
elseif domain_resolver_dns_https then
|
||||
uci:set(appname, cfgid, "domain_resolver_dns_https", domain_resolver_dns_https)
|
||||
uci:set(c_config, cfgid, "domain_resolver_dns_https", domain_resolver_dns_https)
|
||||
end
|
||||
end
|
||||
if domain_strategy then
|
||||
@@ -1968,20 +1969,20 @@ local function update_node(manual)
|
||||
local map = { UseIPv4v6 = "prefer_ipv4", UseIPv6v4 = "prefer_ipv6", UseIPv4 = "ipv4_only", UseIPv6 = "ipv6_only" }
|
||||
ds = map[ds] or ""
|
||||
end
|
||||
uci:set(appname, cfgid, "domain_strategy", ds)
|
||||
uci:set(c_config, cfgid, "domain_strategy", ds)
|
||||
end
|
||||
end
|
||||
-- 订阅组链式代理
|
||||
if chain_node_type ~= "" and kkk == "type" and (vvv == "Xray" or vvv == "sing-box") then
|
||||
if preproxy_node_group ~="" then
|
||||
uci:set(appname, cfgid, "chain_proxy", "1")
|
||||
uci:set(appname, cfgid, "preproxy_node", preproxy_node_group)
|
||||
uci:set(c_config, cfgid, "chain_proxy", "1")
|
||||
uci:set(c_config, cfgid, "preproxy_node", preproxy_node_group)
|
||||
elseif to_node_group ~= "" then
|
||||
uci:set(appname, cfgid, "chain_proxy", "2")
|
||||
uci:set(appname, cfgid, "to_node", to_node_group)
|
||||
uci:set(c_config, cfgid, "chain_proxy", "2")
|
||||
uci:set(c_config, cfgid, "to_node", to_node_group)
|
||||
elseif outbound_iface_group ~= "" then
|
||||
uci:set(appname, cfgid, "chain_proxy", "3")
|
||||
uci:set(appname, cfgid, "outbound_iface", outbound_iface_group)
|
||||
uci:set(c_config, cfgid, "chain_proxy", "3")
|
||||
uci:set(c_config, cfgid, "outbound_iface", outbound_iface_group)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1992,16 +1993,16 @@ local function update_node(manual)
|
||||
for cfgid, info in pairs(subscribe_info) do
|
||||
for key, value in pairs(info) do
|
||||
if value ~= "" then
|
||||
uci:set(appname, cfgid, key, value)
|
||||
uci:set(c_config, cfgid, key, value)
|
||||
else
|
||||
uci:delete(appname, cfgid, key)
|
||||
uci:delete(c_config, cfgid, key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if next(CONFIG) then
|
||||
local nodes = {}
|
||||
uci:foreach(appname, "nodes", function(node)
|
||||
uci:foreach(c_config, "nodes", function(node)
|
||||
nodes[#nodes + 1] = node
|
||||
end)
|
||||
|
||||
@@ -2020,11 +2021,11 @@ local function update_node(manual)
|
||||
end
|
||||
end
|
||||
|
||||
api.uci_save(uci, appname, true)
|
||||
api.uci_save(uci, c_config, true)
|
||||
|
||||
if arg[3] == "cron" then
|
||||
if not fs.access("/var/lock/" .. appname .. ".lock") then
|
||||
luci.sys.call("touch /tmp/lock/" .. appname .. "_cron.lock")
|
||||
if not fs.access("/var/lock/" .. c_config .. ".lock") then
|
||||
luci.sys.call("touch /tmp/lock/" .. c_config .. "_cron.lock")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2133,10 +2134,10 @@ local execute = function()
|
||||
local fail_list = {}
|
||||
if arg[2] ~= "all" then
|
||||
string.gsub(arg[2], '[^' .. "," .. ']+', function(w)
|
||||
subscribe_list[#subscribe_list + 1] = uci:get_all(appname, w) or {}
|
||||
subscribe_list[#subscribe_list + 1] = uci:get_all(c_config, w) or {}
|
||||
end)
|
||||
else
|
||||
uci:foreach(appname, "subscribe_list", function(o)
|
||||
uci:foreach(c_config, "subscribe_list", function(o)
|
||||
subscribe_list[#subscribe_list + 1] = o
|
||||
end)
|
||||
end
|
||||
@@ -2182,7 +2183,7 @@ local execute = function()
|
||||
raw_data = parseClashNode(raw_data)
|
||||
subscribe_info[cfgid] = parse_clash_sub_info(headers)
|
||||
parse_link(raw_data, "2", remark, value)
|
||||
uci:set(appname, cfgid, "md5", new_md5)
|
||||
uci:set(c_config, cfgid, "md5", new_md5)
|
||||
end
|
||||
else
|
||||
fail_list[#fail_list + 1] = value
|
||||
@@ -2216,7 +2217,7 @@ local function check_instance(action)
|
||||
os.exit(0)
|
||||
else
|
||||
luci.sys.call("touch " .. sub_lock)
|
||||
uci:revert(appname)
|
||||
uci:revert(c_config)
|
||||
end
|
||||
elseif action == "end" then
|
||||
luci.sys.call("rm -f " .. sub_lock)
|
||||
|
||||
@@ -204,7 +204,7 @@ end
|
||||
current_node = current_node_id and m:get(current_node_id) or {}
|
||||
|
||||
o = s:option(Flag, "log", translate("Enable Node Log"))
|
||||
o:depends({ _hide_node_option = "1", ['!reverse'] = true })
|
||||
o:depends({ node = "", ['!reverse'] = true })
|
||||
|
||||
o = s:option(ListValue, "loglevel", translate("Log Level"))
|
||||
o.default = "warn"
|
||||
@@ -352,6 +352,10 @@ o:depends("remote_dns_protocol", "http3")
|
||||
o:depends("remote_dns_protocol", "quic")
|
||||
o:depends("remote_dns_protocol", "tls")
|
||||
|
||||
o = s:option(Value, "remote_rewrite_ttl", translate("Remote DNS") .. " TTL")
|
||||
o.datatype = "min(1)"
|
||||
o.default = "30"
|
||||
|
||||
o = s:option(ListValue, "dns_hosts_mode", translate("Domain Override"))
|
||||
o:value("default", translate("Use global config"))
|
||||
o:value("disable", translate("No patterns are used"))
|
||||
@@ -377,6 +381,9 @@ local o_node = s.fields["node"]
|
||||
for k, v in pairs(nodes_table) do
|
||||
o_node:value(v.id, v["remark"])
|
||||
o_node.group[#o_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
|
||||
if v.type == "sing-box" then
|
||||
s.fields["remote_rewrite_ttl"]:depends({ node = v.id })
|
||||
end
|
||||
if v.node_type == "normal" or v.protocol == "_balancing" or v.protocol == "_urltest" then
|
||||
--Shunt node has its own separate options.
|
||||
s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "tcp" })
|
||||
|
||||
@@ -234,6 +234,12 @@ o:value("UseIP")
|
||||
o:value("UseIPv4")
|
||||
o:value("UseIPv6")
|
||||
|
||||
if current_node.type == "sing-box" then
|
||||
o = s:taboption("DNS", Value, "remote_rewrite_ttl", translate("Remote DNS") .. " TTL")
|
||||
o.datatype = "min(1)"
|
||||
o.default = "30"
|
||||
end
|
||||
|
||||
o = s:taboption("DNS", TextValue, "dns_hosts", translate("Domain Override"))
|
||||
o.rows = 5
|
||||
o.wrap = "off"
|
||||
|
||||
@@ -1116,6 +1116,7 @@ function gen_config(var)
|
||||
local remote_dns_query_strategy = var["remote_dns_query_strategy"]
|
||||
local remote_dns_fake = var["remote_dns_fake"]
|
||||
local remote_dns_client_ip = var["remote_dns_client_ip"]
|
||||
local remote_rewrite_ttl = var["remote_rewrite_ttl"] or "30"
|
||||
local dns_cache = var["dns_cache"]
|
||||
local tags = var["tags"]
|
||||
local no_run = var["no_run"]
|
||||
@@ -2026,7 +2027,7 @@ function gen_config(var)
|
||||
end
|
||||
if value.outboundTag ~= "block" and value.outboundTag ~= "direct" then
|
||||
dns_rule.server = "remote"
|
||||
dns_rule.rewrite_ttl = 30
|
||||
dns_rule.rewrite_ttl = tonumber(remote_rewrite_ttl)
|
||||
if true then
|
||||
local block_rule
|
||||
if remote_strategy == "ipv4_only" then
|
||||
@@ -2073,29 +2074,42 @@ function gen_config(var)
|
||||
end
|
||||
end
|
||||
if default_dns_flag == "remote" then
|
||||
local block_rule
|
||||
local dns_rule_query_type = { "A", "AAAA" }
|
||||
if remote_strategy == "ipv4_only" then
|
||||
block_rule = {
|
||||
query_type = { "AAAA" },
|
||||
action = "predefined",
|
||||
rcode = "NOERROR"
|
||||
}
|
||||
dns_rule_query_type = { "A" }
|
||||
elseif remote_strategy == "ipv6_only" then
|
||||
block_rule = {
|
||||
query_type = { "A" },
|
||||
action = "predefined",
|
||||
rcode = "NOERROR"
|
||||
}
|
||||
dns_rule_query_type = { "AAAA" }
|
||||
end
|
||||
if block_rule then
|
||||
table.insert(dns.rules, block_rule)
|
||||
end
|
||||
if remote_dns_fake then
|
||||
-- When default is not direct and enable fakedns, default DNS use FakeDNS.
|
||||
local fakedns_dns_rule = {
|
||||
query_type = dns_rule_query_type,
|
||||
server = fakedns_tag,
|
||||
disable_cache = true,
|
||||
rewrite_ttl = 30
|
||||
rewrite_ttl = tonumber(remote_rewrite_ttl)
|
||||
}
|
||||
table.insert(dns.rules, fakedns_dns_rule)
|
||||
else
|
||||
local remote_dns_rule = {
|
||||
query_type = dns_rule_query_type,
|
||||
server = "remote",
|
||||
disable_cache = true,
|
||||
}
|
||||
table.insert(dns.rules, remote_dns_rule)
|
||||
end
|
||||
local remote_dns_rule = {
|
||||
server = "remote",
|
||||
disable_cache = true,
|
||||
rewrite_ttl = tonumber(remote_rewrite_ttl)
|
||||
}
|
||||
table.insert(dns.rules, remote_dns_rule)
|
||||
end
|
||||
local dns_in_inbound = {
|
||||
type = "direct",
|
||||
|
||||
@@ -201,7 +201,7 @@ run_xray() {
|
||||
|
||||
run_singbox() {
|
||||
local flag node redir_port tcp_proxy_way socks_address socks_port socks_username socks_password http_address http_port http_username http_password
|
||||
local dns_listen_port direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy dns_cache
|
||||
local dns_listen_port direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy remote_rewrite_ttl dns_cache
|
||||
local loglevel log_file config_file
|
||||
eval_set_val $@
|
||||
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||||
@@ -317,6 +317,7 @@ run_singbox() {
|
||||
[ -n "$dns_listen_port" ] && json_add_string "dns_listen_port" "${dns_listen_port}"
|
||||
[ -n "$dns_cache" ] && json_add_string "dns_cache" "${dns_cache}"
|
||||
[ "$remote_fakedns" = "1" ] && json_add_string "remote_dns_fake" "1"
|
||||
[ -n "$remote_rewrite_ttl" ] && json_add_string "remote_rewrite_ttl" "${remote_rewrite_ttl}"
|
||||
}
|
||||
json_add_string "direct_dns_udp_port" "${DIRECT_DNS_UDP_PORT}"
|
||||
json_add_string "direct_dns_udp_server" "${DIRECT_DNS_UDP_SERVER}"
|
||||
@@ -612,6 +613,7 @@ run_global() {
|
||||
|
||||
local _remote_dns_client_ip=$(config_t_get global remote_dns_client_ip)
|
||||
[ -n "${_remote_dns_client_ip}" ] && V2RAY_ARGS="${V2RAY_ARGS} remote_dns_client_ip=${_remote_dns_client_ip}"
|
||||
V2RAY_ARGS="${V2RAY_ARGS} remote_rewrite_ttl=$(config_t_get global remote_rewrite_ttl)"
|
||||
}
|
||||
dns_msg="${dns_msg})"
|
||||
|
||||
@@ -982,7 +984,7 @@ acl_app() {
|
||||
dnsmasq_port=${GLOBAL_DNSMASQ_PORT:-11400}
|
||||
for sid in $items; do
|
||||
index=$(expr $index + 1)
|
||||
local enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy log loglevel log_file
|
||||
local enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy remote_rewrite_ttl log loglevel log_file
|
||||
local _ip _mac _iprange _ipset _ip_or_mac source_list config_file
|
||||
[ "$(config_n_get $sid enabled)" = "1" ] || continue
|
||||
has_enabled=1
|
||||
@@ -1086,7 +1088,8 @@ acl_app() {
|
||||
dns_listen_port=${dns_port} \
|
||||
direct_dns_query_strategy=${direct_dns_query_strategy} \
|
||||
remote_dns_protocol=${remote_dns_protocol} remote_dns_tcp_server=${remote_dns} remote_dns_udp_server=${remote_dns} remote_dns_doh="${remote_dns}" \
|
||||
remote_dns_client_ip=${remote_dns_client_ip} remote_dns_detour=${remote_dns_detour} remote_fakedns=${remote_fakedns} remote_dns_query_strategy=${remote_dns_query_strategy} \
|
||||
remote_dns_client_ip=${remote_dns_client_ip} remote_dns_detour=${remote_dns_detour} remote_dns_query_strategy=${remote_dns_query_strategy} \
|
||||
remote_fakedns=${remote_fakedns} remote_rewrite_ttl=${remote_rewrite_ttl} \
|
||||
config_file=${config_file} \
|
||||
log_file="${log_file}" loglevel="${loglevel}"
|
||||
local status=$?
|
||||
@@ -1108,7 +1111,7 @@ acl_app() {
|
||||
}
|
||||
fi
|
||||
}
|
||||
unset enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy
|
||||
unset enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy remote_rewrite_ttl
|
||||
unset _ip _mac _iprange _ipset _ip_or_mac source_list config_file
|
||||
done
|
||||
unset redir_port dns_port dnsmasq_port
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (C) 2020 Gyj1109
|
||||
# 适配 OpenWrt 25.12 修改版
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-syncthing
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=3
|
||||
|
||||
LUCI_TITLE:=LuCI support for Syncthing
|
||||
LUCI_PKGARCH:=all
|
||||
# 适配 25.12:确保安装了 syncthing 后,LuCI 界面能正确拉起
|
||||
LUCI_DEPENDS:=+syncthing
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# 明确定义配置文件的归属,这对 25.12 的 apk 管理器非常重要
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/syncthing
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
@@ -0,0 +1,2 @@
|
||||
# luci-app-syncthing
|
||||
在Potat0000源码基础上进行了汉化优化,官方openwrt23.05.3编译后可使用
|
||||
@@ -0,0 +1,17 @@
|
||||
module("luci.controller.syncthing", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/syncthing") then
|
||||
return
|
||||
end
|
||||
|
||||
entry({"admin", "services", "syncthing"}, cbi("syncthing"), _("文件同步"), 10).dependent = true
|
||||
entry({"admin", "services", "syncthing", "status"}, call("act_status")).leaf = true
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e = {}
|
||||
e.running = luci.sys.call("pgrep syncthing >/dev/null") == 0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
@@ -0,0 +1,48 @@
|
||||
require("nixio.fs")
|
||||
|
||||
m = Map("syncthing", translate("Syncthing同步工具"))
|
||||
|
||||
m:section(SimpleSection).template = "syncthing/syncthing_status"
|
||||
|
||||
s = m:section(TypedSection, "syncthing")
|
||||
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "enabled", translate("启用"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
|
||||
gui_address = s:option(Value, "gui_address", translate("GUI访问地址"))
|
||||
gui_address.description = translate("使用0.0.0.0以监控所有访问。")
|
||||
gui_address.default = "http://0.0.0.0:8384"
|
||||
gui_address.placeholder = "http://0.0.0.0:8384"
|
||||
gui_address.rmempty = false
|
||||
|
||||
home = s:option(Value, "home", translate("配置文件目录"))
|
||||
home.description = translate("只有保存在/etc/syncthing中的配置会自动备份!")
|
||||
home.default = "/etc/syncthing"
|
||||
home.placeholder = "/etc/syncthing"
|
||||
home.rmempty = false
|
||||
|
||||
user = s:option(ListValue, "user", translate("用户"))
|
||||
user.description = translate("默认是syncthing,但这可能会导致权限被拒绝。Syncthing官方不建议以root身份运行。")
|
||||
user:value("", translate("syncthing"))
|
||||
for u in luci.util.execi("cat /etc/passwd | cut -d ':' -f1") do
|
||||
user:value(u)
|
||||
end
|
||||
|
||||
macprocs = s:option(Value, "macprocs", translate("线程限制"))
|
||||
macprocs.description = translate("0表示匹配CPU数量(默认),>0表示显式指定并发数。")
|
||||
macprocs.default = "0"
|
||||
macprocs.placeholder = "0"
|
||||
macprocs.datatype = "range(0,32)"
|
||||
macprocs.rmempty = false
|
||||
|
||||
nice = s:option(Value, "nice", translate("优先级"))
|
||||
nice.description = translate("显式指定优先级值。0是最高,19是最低。(暂时不允许设置负值)")
|
||||
nice.default = "19"
|
||||
nice.placeholder = "19"
|
||||
nice.datatype = "range(0,19)"
|
||||
nice.rmempty = false
|
||||
|
||||
return m
|
||||
@@ -0,0 +1,27 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(1, '<%=url([[admin]], [[services]], [[syncthing]], [[status]])%>', null,
|
||||
function (x, data) {
|
||||
var tb = document.getElementById('syncthing_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
var links = '<em><b><font color="green">Syncthing <%:运行中%></font></b></em><input class="btn cbi-button mar-10" type="button" value="<%:打开Syncthing页面%>" onclick="openwebui();" />';
|
||||
tb.innerHTML = links;
|
||||
} else {
|
||||
tb.innerHTML = '<em><b><font color="red">Syncthing <%:未运行%></font></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function openwebui(){
|
||||
var url = window.location.host+":<%=luci.sys.exec("uci -q get syncthing.syncthing.gui_address"):match(":[0-9]+"):gsub(":", "")%>";
|
||||
window.open('http://'+url,'target','');
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="syncthing_status">
|
||||
<em><%:正在收集数据...%></em>
|
||||
</p>
|
||||
</fieldset>
|
||||
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
touch /etc/config/syncthing
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@syncthing[-1]
|
||||
add ucitrack syncthing
|
||||
set ucitrack.@syncthing[-1].exec='/etc/init.d/syncthing stop && /etc/init.d/syncthing start'
|
||||
commit ucitrack
|
||||
EOF
|
||||
# remove LuCI cache
|
||||
rm -f /tmp/luci*
|
||||
exit 0
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-syncthing": {
|
||||
"description": "Grant UCI access for luci-app-syncthing",
|
||||
"read": {
|
||||
"uci": [ "syncthing" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "syncthing" ]
|
||||
}
|
||||
}
|
||||
}
|
||||