mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-10-31 16:45:13 +08:00
update 2026-05-23 14:30:42
This commit is contained in:
1 parent
10df4c0e7e
commit
9a8249c408
17 files changed
+283
-71
No files matched your search
@@ -59,6 +59,7 @@ function index()
|
|||||||
entry({"admin", "services", appname, "server_user"}, cbi(appname .. "/server/user")).leaf = true
|
entry({"admin", "services", appname, "server_user"}, cbi(appname .. "/server/user")).leaf = true
|
||||||
|
|
||||||
--[[ API ]]
|
--[[ API ]]
|
||||||
|
entry({"admin", "services", appname, "server_user_update"}, call("server_user_update")).leaf = true
|
||||||
entry({"admin", "services", appname, "server_user_status"}, call("server_user_status")).leaf = true
|
entry({"admin", "services", appname, "server_user_status"}, call("server_user_status")).leaf = true
|
||||||
entry({"admin", "services", appname, "server_user_log"}, call("server_user_log")).leaf = true
|
entry({"admin", "services", appname, "server_user_log"}, call("server_user_log")).leaf = true
|
||||||
entry({"admin", "services", appname, "server_get_log"}, call("server_get_log")).leaf = true
|
entry({"admin", "services", appname, "server_get_log"}, call("server_get_log")).leaf = true
|
||||||
@@ -730,6 +731,23 @@ function rollback_rules()
|
|||||||
http_write_json_ok()
|
http_write_json_ok()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function server_user_update()
|
||||||
|
local id = http.formvalue("id") -- Node id
|
||||||
|
local data = http.formvalue("data") -- json new Data
|
||||||
|
if id and data then
|
||||||
|
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)
|
||||||
|
end
|
||||||
|
api.uci_save(uci, appname .. "_server")
|
||||||
|
http_write_json_ok()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
http_write_json_error()
|
||||||
|
end
|
||||||
|
|
||||||
function server_user_status()
|
function server_user_status()
|
||||||
local e = {}
|
local e = {}
|
||||||
e.index = http.formvalue("index")
|
e.index = http.formvalue("index")
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ formvalue_key = "cbid." .. appname .. "." .. arg[1] .. "."
|
|||||||
|
|
||||||
local header = Template(appname .. "/node_config/header")
|
local header = Template(appname .. "/node_config/header")
|
||||||
header.api = api
|
header.api = api
|
||||||
|
header.config = m.config
|
||||||
header.section = arg[1]
|
header.section = arg[1]
|
||||||
m:append(header)
|
m:append(header)
|
||||||
|
|
||||||
@@ -117,6 +118,7 @@ end
|
|||||||
|
|
||||||
local footer = Template(appname .. "/node_config/footer")
|
local footer = Template(appname .. "/node_config/footer")
|
||||||
footer.api = api
|
footer.api = api
|
||||||
|
footer.config = m.config
|
||||||
footer.section = arg[1]
|
footer.section = arg[1]
|
||||||
|
|
||||||
m:append(footer)
|
m:append(footer)
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
local m, s = ...
|
local m, s = ...
|
||||||
|
|
||||||
local api = require "luci.passwall.api"
|
|
||||||
|
|
||||||
if not api.finded_com("hysteria") then
|
if not api.finded_com("hysteria") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -10,21 +8,24 @@ local fs = api.fs
|
|||||||
|
|
||||||
local type_name = "Hysteria2"
|
local type_name = "Hysteria2"
|
||||||
|
|
||||||
|
-- [[ Hysteria2 ]]
|
||||||
|
|
||||||
|
s.fields["type"]:value(type_name, "Hysteria2")
|
||||||
|
|
||||||
|
if s.val["type"] and s.val["type"] ~= type_name then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local option_prefix = "hysteria2_"
|
local option_prefix = "hysteria2_"
|
||||||
|
|
||||||
local function _n(name)
|
local function _n(name)
|
||||||
return option_prefix .. name
|
return option_prefix .. name
|
||||||
end
|
end
|
||||||
|
|
||||||
-- [[ Hysteria2 ]]
|
|
||||||
|
|
||||||
s.fields["type"]:value(type_name, "Hysteria2")
|
|
||||||
|
|
||||||
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
|
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
|
||||||
|
|
||||||
o = s:option(Value, _n("port"), translate("Listen Port"))
|
o = s:option(Value, _n("port"), translate("Listen Port"))
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
o.rmempty = false
|
|
||||||
o:depends({ [_n("custom")] = false })
|
o:depends({ [_n("custom")] = false })
|
||||||
|
|
||||||
o = s:option(Flag, _n("realms"), translate("Realms"))
|
o = s:option(Flag, _n("realms"), translate("Realms"))
|
||||||
|
|||||||
@@ -1,15 +1,22 @@
|
|||||||
local m, s = ...
|
local m, s = ...
|
||||||
|
|
||||||
local api = require "luci.passwall.api"
|
|
||||||
|
|
||||||
if not api.finded_com("xray") then
|
if not api.finded_com("xray") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local fs = api.fs
|
|
||||||
|
|
||||||
local type_name = "Xray"
|
local type_name = "Xray"
|
||||||
|
|
||||||
|
-- [[ Xray ]]
|
||||||
|
|
||||||
|
s.fields["type"]:value(type_name, "Xray")
|
||||||
|
if not s.fields["type"].default then
|
||||||
|
s.fields["type"].default = type_name
|
||||||
|
end
|
||||||
|
|
||||||
|
if s.val["type"] and s.val["type"] ~= type_name then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local option_prefix = "xray_"
|
local option_prefix = "xray_"
|
||||||
|
|
||||||
local function _n(name)
|
local function _n(name)
|
||||||
@@ -24,10 +31,6 @@ local header_type_list = {
|
|||||||
"none", "srtp", "utp", "wechat-video", "dtls", "wireguard", "dns"
|
"none", "srtp", "utp", "wechat-video", "dtls", "wireguard", "dns"
|
||||||
}
|
}
|
||||||
|
|
||||||
-- [[ Xray ]]
|
|
||||||
|
|
||||||
s.fields["type"]:value(type_name, "Xray")
|
|
||||||
|
|
||||||
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
|
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
|
||||||
|
|
||||||
o = s:option(ListValue, _n("protocol"), translate("Protocol"))
|
o = s:option(ListValue, _n("protocol"), translate("Protocol"))
|
||||||
|
|||||||
@@ -1,34 +1,37 @@
|
|||||||
local m, s = ...
|
local m, s = ...
|
||||||
|
|
||||||
local api = require "luci.passwall.api"
|
|
||||||
|
|
||||||
local singbox_bin = api.finded_com("sing-box")
|
local singbox_bin = api.finded_com("sing-box")
|
||||||
|
|
||||||
if not singbox_bin then
|
if not singbox_bin then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local fs = api.fs
|
|
||||||
|
|
||||||
local singbox_tags = luci.sys.exec(singbox_bin .. " version | grep 'Tags:' | awk '{print $2}'")
|
|
||||||
|
|
||||||
local type_name = "sing-box"
|
local type_name = "sing-box"
|
||||||
|
|
||||||
|
-- [[ Sing-Box ]]
|
||||||
|
|
||||||
|
s.fields["type"]:value(type_name, "Sing-Box")
|
||||||
|
if not s.fields["type"].default then
|
||||||
|
s.fields["type"].default = type_name
|
||||||
|
end
|
||||||
|
|
||||||
|
if s.val["type"] and s.val["type"] ~= type_name then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local option_prefix = "singbox_"
|
local option_prefix = "singbox_"
|
||||||
|
|
||||||
local function _n(name)
|
local function _n(name)
|
||||||
return option_prefix .. name
|
return option_prefix .. name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local singbox_tags = luci.sys.exec(singbox_bin .. " version | grep 'Tags:' | awk '{print $2}'")
|
||||||
|
|
||||||
local ss_method_list = {
|
local ss_method_list = {
|
||||||
"none", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305",
|
"none", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305",
|
||||||
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
||||||
}
|
}
|
||||||
|
|
||||||
-- [[ Sing-Box ]]
|
|
||||||
|
|
||||||
s.fields["type"]:value(type_name, "Sing-Box")
|
|
||||||
|
|
||||||
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
|
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
|
||||||
|
|
||||||
o = s:option(ListValue, _n("protocol"), translate("Protocol"))
|
o = s:option(ListValue, _n("protocol"), translate("Protocol"))
|
||||||
@@ -55,7 +58,6 @@ o:depends({ [_n("custom")] = false })
|
|||||||
|
|
||||||
o = s:option(Value, _n("port"), translate("Listen Port"))
|
o = s:option(Value, _n("port"), translate("Listen Port"))
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
o.rmempty = false
|
|
||||||
o:depends({ [_n("custom")] = false })
|
o:depends({ [_n("custom")] = false })
|
||||||
|
|
||||||
o = s:option(Flag, _n("auth"), translate("Auth"))
|
o = s:option(Flag, _n("auth"), translate("Auth"))
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
local m, s = ...
|
local m, s = ...
|
||||||
|
|
||||||
local api = require "luci.passwall.api"
|
|
||||||
|
|
||||||
if not api.is_finded("microsocks") then
|
if not api.is_finded("microsocks") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -17,6 +15,13 @@ end
|
|||||||
-- [[ microsocks ]]
|
-- [[ microsocks ]]
|
||||||
|
|
||||||
s.fields["type"]:value(type_name, "Socks")
|
s.fields["type"]:value(type_name, "Socks")
|
||||||
|
if not s.fields["type"].default then
|
||||||
|
s.fields["type"].default = type_name
|
||||||
|
end
|
||||||
|
|
||||||
|
if s.val["type"] and s.val["type"] ~= type_name then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
o = s:option(Value, _n("port"), translate("Listen Port"))
|
o = s:option(Value, _n("port"), translate("Listen Port"))
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
local m, s = ...
|
local m, s = ...
|
||||||
|
|
||||||
local api = require "luci.passwall.api"
|
|
||||||
|
|
||||||
if not api.is_finded("ssserver") then
|
if not api.is_finded("ssserver") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local type_name = "SS-Rust"
|
local type_name = "SS-Rust"
|
||||||
|
|
||||||
|
-- [[ Shadowsocks Rust ]]
|
||||||
|
|
||||||
|
s.fields["type"]:value(type_name, translate("Shadowsocks Rust"))
|
||||||
|
|
||||||
|
if s.val["type"] and s.val["type"] ~= type_name then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local option_prefix = "ssrust_"
|
local option_prefix = "ssrust_"
|
||||||
|
|
||||||
local function _n(name)
|
local function _n(name)
|
||||||
@@ -20,10 +26,6 @@ local ssrust_encrypt_method_list = {
|
|||||||
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
||||||
}
|
}
|
||||||
|
|
||||||
-- [[ Shadowsocks Rust ]]
|
|
||||||
|
|
||||||
s.fields["type"]:value(type_name, translate("Shadowsocks Rust"))
|
|
||||||
|
|
||||||
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
|
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
|
||||||
|
|
||||||
o = s:option(Value, _n("port"), translate("Listen Port"))
|
o = s:option(Value, _n("port"), translate("Listen Port"))
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
local m, s = ...
|
local m, s = ...
|
||||||
|
|
||||||
local api = require "luci.passwall.api"
|
|
||||||
|
|
||||||
if not api.is_finded("ssr-server") then
|
if not api.is_finded("ssr-server") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local type_name = "SSR"
|
local type_name = "SSR"
|
||||||
|
|
||||||
|
-- [[ ShadowsocksR ]]
|
||||||
|
|
||||||
|
s.fields["type"]:value(type_name, translate("ShadowsocksR"))
|
||||||
|
|
||||||
|
if s.val["type"] and s.val["type"] ~= type_name then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local option_prefix = "ssr_"
|
local option_prefix = "ssr_"
|
||||||
|
|
||||||
local function _n(name)
|
local function _n(name)
|
||||||
@@ -33,10 +39,6 @@ local ssr_obfs_list = {
|
|||||||
"tls1.0_session_auth", "tls1.2_ticket_auth"
|
"tls1.0_session_auth", "tls1.2_ticket_auth"
|
||||||
}
|
}
|
||||||
|
|
||||||
-- [[ ShadowsocksR ]]
|
|
||||||
|
|
||||||
s.fields["type"]:value(type_name, translate("ShadowsocksR"))
|
|
||||||
|
|
||||||
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
|
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
|
||||||
|
|
||||||
o = s:option(Value, _n("port"), translate("Listen Port"))
|
o = s:option(Value, _n("port"), translate("Listen Port"))
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
local api = require "luci.passwall.api"
|
api = require "luci.passwall.api"
|
||||||
local appname = api.appname
|
appname = api.appname
|
||||||
local fs = api.fs
|
fs = api.fs
|
||||||
local types_dir = "/usr/lib/lua/luci/model/cbi/" .. appname .. "/server/type/"
|
|
||||||
|
|
||||||
m = Map("passwall_server", translate("Server Config"))
|
m = Map("passwall_server", translate("Server Config"))
|
||||||
m.redirect = api.url("server")
|
m.redirect = api.url("server")
|
||||||
@@ -11,12 +10,21 @@ if not arg[1] or not m:get(arg[1]) then
|
|||||||
luci.http.redirect(m.redirect)
|
luci.http.redirect(m.redirect)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local header = Template(appname .. "/server/config_header")
|
||||||
|
header.api = api
|
||||||
|
header.config = m.config
|
||||||
|
header.section = arg[1]
|
||||||
|
m:append(header)
|
||||||
|
|
||||||
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
|
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
|
||||||
|
|
||||||
s = m:section(NamedSection, arg[1], "user", "")
|
s = m:section(NamedSection, arg[1], "user", "")
|
||||||
s.addremove = false
|
s.addremove = false
|
||||||
s.dynamic = false
|
s.dynamic = false
|
||||||
|
|
||||||
|
local types_dir = "/usr/lib/lua/luci/model/cbi/" .. appname .. "/server/type/"
|
||||||
|
s.val = m:get(arg[1]) or {}
|
||||||
|
|
||||||
o = s:option(Flag, "enable", translate("Enable"))
|
o = s:option(Flag, "enable", translate("Enable"))
|
||||||
o.default = "1"
|
o.default = "1"
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
@@ -32,9 +40,9 @@ for filename in fs.dir(types_dir) do
|
|||||||
table.insert(type_table, filename)
|
table.insert(type_table, filename)
|
||||||
end
|
end
|
||||||
table.sort(type_table, function(a, b)
|
table.sort(type_table, function(a, b)
|
||||||
if a == "socks.lua" then return true end
|
if a == "socks.lua" then return true end
|
||||||
if b == "socks.lua" then return false end
|
if b == "socks.lua" then return false end
|
||||||
return a < b
|
return a < b
|
||||||
end)
|
end)
|
||||||
|
|
||||||
for index, value in ipairs(type_table) do
|
for index, value in ipairs(type_table) do
|
||||||
@@ -42,4 +50,10 @@ for index, value in ipairs(type_table) do
|
|||||||
setfenv(p_func, getfenv(1))(m, s)
|
setfenv(p_func, getfenv(1))(m, s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local footer = Template(appname .. "/server/config_footer")
|
||||||
|
footer.api = api
|
||||||
|
footer.config = m.config
|
||||||
|
footer.section = arg[1]
|
||||||
|
m:append(footer)
|
||||||
|
|
||||||
return m
|
return m
|
||||||
@@ -1293,6 +1293,11 @@ function to_check_self()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function luci_types(id, m, s, type_name, option_prefix)
|
function luci_types(id, m, s, type_name, option_prefix)
|
||||||
|
local fv_type
|
||||||
|
local field_type = s.fields["type"]
|
||||||
|
if field_type then
|
||||||
|
fv_type = field_type:formvalue(id)
|
||||||
|
end
|
||||||
local rewrite_option_table = {}
|
local rewrite_option_table = {}
|
||||||
for key, value in pairs(s.fields) do
|
for key, value in pairs(s.fields) do
|
||||||
if key:find(option_prefix) == 1 then
|
if key:find(option_prefix) == 1 then
|
||||||
@@ -1361,6 +1366,10 @@ function luci_types(id, m, s, type_name, option_prefix)
|
|||||||
else
|
else
|
||||||
s.fields[key]:depends({ type = type_name })
|
s.fields[key]:depends({ type = type_name })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if fv_type and fv_type ~= type_name then
|
||||||
|
s.fields[key].rmempty = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ local api = self.api
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
//<![CDATA[
|
//<![CDATA[
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
waitForElement('select[name*="<%=api.appname%>"][name*="type"]', function(el) {
|
waitForElement('select[name*="<%=self.config%>"][name*="type"]', function(el) {
|
||||||
let o_val = el.value;
|
let o_val = el.value;
|
||||||
el.addEventListener("change", () => {
|
el.addEventListener("change", () => {
|
||||||
el.blur();
|
el.blur();
|
||||||
@@ -22,7 +22,7 @@ local api = self.api
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
waitForElement('select[name*="<%=api.appname%>"][name*="protocol"]', function(el) {
|
waitForElement('select[name*="<%=self.config%>"][name*="protocol"]', function(el) {
|
||||||
let o_val = el.value;
|
let o_val = el.value;
|
||||||
el.addEventListener("change", () => {
|
el.addEventListener("change", () => {
|
||||||
el.blur();
|
el.blur();
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ local api = self.api
|
|||||||
|
|
||||||
function getOption(opt) {
|
function getOption(opt) {
|
||||||
var obj;
|
var obj;
|
||||||
var id = 'cbid.<%=api.appname%>.' + node_id + '.' + opt;
|
var id = 'cbid.<%=self.config%>.' + node_id + '.' + opt;
|
||||||
obj = document.getElementsByName(id)[0] || document.getElementById(id);
|
obj = document.getElementsByName(id)[0] || document.getElementById(id);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
var combobox = document.getElementById('cbi.combobox.' + id);
|
var combobox = document.getElementById('cbi.combobox.' + id);
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<%
|
||||||
|
local api = self.api
|
||||||
|
-%>
|
||||||
|
<script type="text/javascript">
|
||||||
|
//<![CDATA[
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
waitForElement('select[name*="<%=self.config%>"][name*="type"]', function(el) {
|
||||||
|
let o_val = el.value;
|
||||||
|
el.addEventListener("change", () => {
|
||||||
|
el.blur();
|
||||||
|
if (o_val != el.value) {
|
||||||
|
let save = true;
|
||||||
|
if (save) {
|
||||||
|
//document.getElementsByClassName('cbi-button-save')[0].click();
|
||||||
|
update_node({
|
||||||
|
enable: getOption("enable").value,
|
||||||
|
remarks: getOption("remarks").value,
|
||||||
|
type: getOption("type").value,
|
||||||
|
protocol: ''
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//]]>
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
<%
|
||||||
|
local api = self.api
|
||||||
|
-%>
|
||||||
|
<script type="text/javascript">
|
||||||
|
//<![CDATA[
|
||||||
|
let node_id = "<%=self.section%>";
|
||||||
|
let node_config_url = '<%=api.url("server_user")%>/' + node_id;
|
||||||
|
|
||||||
|
function waitForElement(selector, callback) {
|
||||||
|
const el = document.querySelector(selector);
|
||||||
|
if (el) return callback(el);
|
||||||
|
const observer = new MutationObserver(() => {
|
||||||
|
const el = document.querySelector(selector);
|
||||||
|
if (el) {
|
||||||
|
observer.disconnect();
|
||||||
|
callback(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
observer.observe(document.body, { childList: true, subtree: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOption(opt) {
|
||||||
|
var obj;
|
||||||
|
var id = 'cbid.<%=self.config%>.' + node_id + '.' + opt;
|
||||||
|
obj = document.getElementsByName(id)[0] || document.getElementById(id);
|
||||||
|
if (obj) {
|
||||||
|
var combobox = document.getElementById('cbi.combobox.' + id);
|
||||||
|
if (combobox) {
|
||||||
|
obj.combobox = combobox;
|
||||||
|
}
|
||||||
|
var div = document.getElementById(id);
|
||||||
|
if (div && div.getElementsByTagName("li").length > 0) {
|
||||||
|
obj = div;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_node(data) {
|
||||||
|
XHR.get('<%=api.url("server_user_update")%>', {
|
||||||
|
id: node_id,
|
||||||
|
data: JSON.stringify(data)
|
||||||
|
},
|
||||||
|
function(x, data) {
|
||||||
|
if (x && x.status == 200 && data.code == 1) {
|
||||||
|
window.location.href = node_config_url;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert("<%:Error%>");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//]]>
|
||||||
|
</script>
|
||||||
@@ -1322,7 +1322,7 @@ function act_ping()
|
|||||||
|
|
||||||
if not e.ping then
|
if not e.ping then
|
||||||
local icmp_cmd = string.format("ping -c 1 -W 1 %s 2>/dev/null | grep -o 'time=[0-9.]*' | cut -d= -f2", domain)
|
local icmp_cmd = string.format("ping -c 1 -W 1 %s 2>/dev/null | grep -o 'time=[0-9.]*' | cut -d= -f2", domain)
|
||||||
e.ping = tonumber(luci.sys.exec(icmp_cmd))
|
e.ping = normalize_ping_ms(tonumber(luci.sys.exec(icmp_cmd)))
|
||||||
end
|
end
|
||||||
if not e.ping then
|
if not e.ping then
|
||||||
e.ping = 0
|
e.ping = 0
|
||||||
@@ -1332,7 +1332,7 @@ function act_ping()
|
|||||||
local result = ""
|
local result = ""
|
||||||
local success = false
|
local success = false
|
||||||
local icmp_cmd = string.format("ping -c 1 -W 1 %s 2>/dev/null | grep -o 'time=[0-9.]*' | cut -d= -f2", domain)
|
local icmp_cmd = string.format("ping -c 1 -W 1 %s 2>/dev/null | grep -o 'time=[0-9.]*' | cut -d= -f2", domain)
|
||||||
e.ping = tonumber(luci.sys.exec(icmp_cmd))
|
e.ping = normalize_ping_ms(tonumber(luci.sys.exec(icmp_cmd)))
|
||||||
-- WebSocket 探测 (适用于域名,或带 SNI 的 IP)
|
-- WebSocket 探测 (适用于域名,或带 SNI 的 IP)
|
||||||
if not is_ip or probe_host ~= domain then
|
if not is_ip or probe_host ~= domain then
|
||||||
local resolve_arg = ""
|
local resolve_arg = ""
|
||||||
@@ -1403,7 +1403,7 @@ function act_ping()
|
|||||||
end
|
end
|
||||||
if not e.ping then
|
if not e.ping then
|
||||||
local icmp_cmd = string.format("ping -c 1 -W 1 %s 2>/dev/null | grep -o 'time=[0-9.]*' | cut -d= -f2", domain)
|
local icmp_cmd = string.format("ping -c 1 -W 1 %s 2>/dev/null | grep -o 'time=[0-9.]*' | cut -d= -f2", domain)
|
||||||
e.ping = tonumber(luci.sys.exec(icmp_cmd))
|
e.ping = normalize_ping_ms(tonumber(luci.sys.exec(icmp_cmd)))
|
||||||
end
|
end
|
||||||
|
|
||||||
if not e.ping then
|
if not e.ping then
|
||||||
@@ -1453,10 +1453,6 @@ function act_ping()
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
if e.ping then
|
|
||||||
e.ping = math.floor(e.ping + 0.5)
|
|
||||||
end
|
|
||||||
|
|
||||||
luci.http.prepare_content("application/json")
|
luci.http.prepare_content("application/json")
|
||||||
luci.http.write_json(e)
|
luci.http.write_json(e)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2271,16 +2271,41 @@ start() {
|
|||||||
echolog "禁止连接的域名加载完毕。"
|
echolog "禁止连接的域名加载完毕。"
|
||||||
if [ "$(uci_get_by_type global adblock 0)" == "1" ]; then
|
if [ "$(uci_get_by_type global adblock 0)" == "1" ]; then
|
||||||
echolog "未启动主节点,广告过滤正在加载。"
|
echolog "未启动主节点,广告过滤正在加载。"
|
||||||
cp -f /etc/ssrplus/ad.conf $TMP_DNSMASQ_PATH/
|
cp -f /etc/ssrplus/ad.conf "$TMP_DNSMASQ_PATH/"
|
||||||
if [ -f "$TMP_DNSMASQ_PATH/ad.conf" ]; then
|
if [ -f "$TMP_DNSMASQ_PATH/ad.conf" ]; then
|
||||||
# Optimize: Batch filter using grep instead of looping sed
|
# Optimize: Batch filter using grep instead of looping sed
|
||||||
for list_file in /etc/ssrplus/black.list /etc/ssrplus/white.list /etc/ssrplus/deny.list; do
|
for list_file in /etc/ssrplus/black.list /etc/ssrplus/white.list /etc/ssrplus/deny.list; do
|
||||||
if [ -s "$list_file" ]; then
|
if [ -s "$list_file" ]; then
|
||||||
# Clean list file (remove comments and empty lines)
|
# Clean list file (remove comments and empty lines)
|
||||||
grep -vE '^\s*#|^\s*$' "$list_file" > "${list_file}.clean"
|
grep -vE '^\s*#|^\s*$' "$list_file" | sed 's/\r//g' > "${list_file}.clean"
|
||||||
if [ -s "${list_file}.clean" ]; then
|
if [ -s "${list_file}.clean" ]; then
|
||||||
grep -v -F -f "${list_file}.clean" "$TMP_DNSMASQ_PATH/ad.conf" > "$TMP_DNSMASQ_PATH/ad.conf.tmp"
|
tmp_file="$TMP_DNSMASQ_PATH/ad.conf.tmp"
|
||||||
mv "$TMP_DNSMASQ_PATH/ad.conf.tmp" "$TMP_DNSMASQ_PATH/ad.conf"
|
awk -v list="${list_file}.clean" '
|
||||||
|
BEGIN {
|
||||||
|
while ((getline line < list) > 0) {
|
||||||
|
gsub(/\r/, "", line)
|
||||||
|
if (line != "") {
|
||||||
|
domain[line] = 1
|
||||||
|
# 支持泛域名
|
||||||
|
domain["*." line] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(list)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
keep = 1
|
||||||
|
# 匹配 server=/domain/
|
||||||
|
if (match($0, /^server=\/([^\/]+)\//, m)) {
|
||||||
|
if (m[1] in domain) keep = 0
|
||||||
|
}
|
||||||
|
# 匹配 ipset=/domain/
|
||||||
|
if (match($0, /^ipset=\/([^\/]+)\//, m)) {
|
||||||
|
if (m[1] in domain) keep = 0
|
||||||
|
}
|
||||||
|
if (keep) print
|
||||||
|
}
|
||||||
|
' "$TMP_DNSMASQ_PATH/ad.conf" > "$tmp_file"
|
||||||
|
mv "$tmp_file" "$TMP_DNSMASQ_PATH/ad.conf"
|
||||||
fi
|
fi
|
||||||
rm -f "${list_file}.clean"
|
rm -f "${list_file}.clean"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -45,13 +45,37 @@ done
|
|||||||
# Optimize: Batch filter using grep
|
# Optimize: Batch filter using grep
|
||||||
for list_file in /etc/ssrplus/black.list /etc/ssrplus/white.list /etc/ssrplus/deny.list; do
|
for list_file in /etc/ssrplus/black.list /etc/ssrplus/white.list /etc/ssrplus/deny.list; do
|
||||||
if [ -s "$list_file" ]; then
|
if [ -s "$list_file" ]; then
|
||||||
grep -vE '^\s*#|^\s*$' "$list_file" > "${list_file}.clean"
|
# 清理注释和空行
|
||||||
|
grep -vE '^\s*#|^\s*$' "$list_file" | sed 's/\r//g' > "${list_file}.clean"
|
||||||
if [ -s "${list_file}.clean" ]; then
|
if [ -s "${list_file}.clean" ]; then
|
||||||
for target_file in "$TMP_DNSMASQ_PATH/gfw_list.conf" "$TMP_DNSMASQ_PATH/gfw_base.conf"; do
|
for target_file in "$TMP_DNSMASQ_PATH/gfw_list.conf" "$TMP_DNSMASQ_PATH/gfw_base.conf"; do
|
||||||
if [ -f "$target_file" ]; then
|
[ -f "$target_file" ] || continue
|
||||||
grep -v -F -f "${list_file}.clean" "$target_file" > "${target_file}.tmp"
|
tmp_file="${target_file}.tmp"
|
||||||
mv "${target_file}.tmp" "$target_file"
|
awk -v list="${list_file}.clean" '
|
||||||
fi
|
BEGIN {
|
||||||
|
while ((getline line < list) > 0) {
|
||||||
|
gsub(/\r/, "", line)
|
||||||
|
if (line != "") {
|
||||||
|
domain[line] = 1
|
||||||
|
# 同时支持 *.domain
|
||||||
|
domain["*." line] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(list)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# 提取 server=/domain/xxx
|
||||||
|
if (match($0, /^server=\/([^\/]+)\//, m)) {
|
||||||
|
if (m[1] in domain) next
|
||||||
|
}
|
||||||
|
# 提取 ipset=/domain/xxx
|
||||||
|
if (match($0, /^ipset=\/([^\/]+)\//, m)) {
|
||||||
|
if (m[1] in domain) next
|
||||||
|
}
|
||||||
|
print
|
||||||
|
}
|
||||||
|
' "$target_file" > "$tmp_file"
|
||||||
|
mv "$tmp_file" "$target_file"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
rm -f "${list_file}.clean"
|
rm -f "${list_file}.clean"
|
||||||
@@ -69,19 +93,45 @@ fi
|
|||||||
cat /etc/ssrplus/deny.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/address=\/&\//" >$TMP_DNSMASQ_PATH/denylist.conf
|
cat /etc/ssrplus/deny.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/address=\/&\//" >$TMP_DNSMASQ_PATH/denylist.conf
|
||||||
|
|
||||||
if [ "$(uci_get_by_type global adblock 0)" == "1" ]; then
|
if [ "$(uci_get_by_type global adblock 0)" == "1" ]; then
|
||||||
cp -f /etc/ssrplus/ad.conf $TMP_DNSMASQ_PATH/
|
cp -f /etc/ssrplus/ad.conf "$TMP_DNSMASQ_PATH/"
|
||||||
if [ -f "$TMP_DNSMASQ_PATH/ad.conf" ]; then
|
if [ -f "$TMP_DNSMASQ_PATH/ad.conf" ]; then
|
||||||
for list_file in /etc/ssrplus/black.list /etc/ssrplus/white.list /etc/ssrplus/deny.list; do
|
for list_file in /etc/ssrplus/black.list /etc/ssrplus/white.list /etc/ssrplus/deny.list; do
|
||||||
if [ -s "$list_file" ]; then
|
if [ -s "$list_file" ]; then
|
||||||
grep -vE '^\s*#|^\s*$' "$list_file" > "${list_file}.clean"
|
# 清理注释 & 空行
|
||||||
|
grep -vE '^\s*#|^\s*$' "$list_file" | sed 's/\r//g' > "${list_file}.clean"
|
||||||
if [ -s "${list_file}.clean" ]; then
|
if [ -s "${list_file}.clean" ]; then
|
||||||
grep -v -F -f "${list_file}.clean" "$TMP_DNSMASQ_PATH/ad.conf" > "$TMP_DNSMASQ_PATH/ad.conf.tmp"
|
tmp_file="$TMP_DNSMASQ_PATH/ad.conf.tmp"
|
||||||
mv "$TMP_DNSMASQ_PATH/ad.conf.tmp" "$TMP_DNSMASQ_PATH/ad.conf"
|
awk -v list="${list_file}.clean" '
|
||||||
|
BEGIN {
|
||||||
|
while ((getline line < list) > 0) {
|
||||||
|
gsub(/\r/, "", line)
|
||||||
|
if (line != "") {
|
||||||
|
domain[line] = 1
|
||||||
|
# 支持泛域名
|
||||||
|
domain["*." line] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(list)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
keep = 1
|
||||||
|
# 精确匹配 server=/domain/
|
||||||
|
if (match($0, /^server=\/([^\/]+)\//, m)) {
|
||||||
|
if (m[1] in domain) keep = 0
|
||||||
|
}
|
||||||
|
# 精确匹配 ipset=/domain/
|
||||||
|
if (match($0, /^ipset=\/([^\/]+)\//, m)) {
|
||||||
|
if (m[1] in domain) keep = 0
|
||||||
|
}
|
||||||
|
if (keep) print
|
||||||
|
}
|
||||||
|
' "$TMP_DNSMASQ_PATH/ad.conf" > "$tmp_file"
|
||||||
|
mv "$tmp_file" "$TMP_DNSMASQ_PATH/ad.conf"
|
||||||
fi
|
fi
|
||||||
rm -f "${list_file}.clean"
|
rm -f "${list_file}.clean"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
rm -f $TMP_DNSMASQ_PATH/ad.conf
|
rm -f "$TMP_DNSMASQ_PATH/ad.conf"
|
||||||
fi
|
fi
|
||||||
Reference in new issue
Block a user