luci: optimization

This commit is contained in:
xiaorouji 2024-01-29 01:36:47 +08:00 committed by sbwml
parent 637373e639
commit 463d899505
13 changed files with 171 additions and 172 deletions

View File

@ -246,16 +246,15 @@ function ping_node()
local index = luci.http.formvalue("index") local index = luci.http.formvalue("index")
local address = luci.http.formvalue("address") local address = luci.http.formvalue("address")
local port = luci.http.formvalue("port") local port = luci.http.formvalue("port")
local type = luci.http.formvalue("type") or "icmp"
local e = {} local e = {}
e.index = index e.index = index
local nodes_ping = ucic:get(appname, "@global_other[0]", "nodes_ping") or "" if type == "tcping" and luci.sys.exec("echo -n $(command -v tcping)") ~= "" then
if nodes_ping:find("tcping") and luci.sys.exec("echo -n $(command -v tcping)") ~= "" then
if api.is_ipv6(address) then if api.is_ipv6(address) then
address = api.get_ipv6_only(address) address = api.get_ipv6_only(address)
end end
e.ping = luci.sys.exec(string.format("echo -n $(tcping -q -c 1 -i 1 -t 2 -p %s %s 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null", port, address)) e.ping = luci.sys.exec(string.format("echo -n $(tcping -q -c 1 -i 1 -t 2 -p %s %s 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null", port, address))
end else
if e.ping == nil or tonumber(e.ping) == 0 then
e.ping = luci.sys.exec("echo -n $(ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null" % address) e.ping = luci.sys.exec("echo -n $(ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null" % address)
end end
luci.http.prepare_content("application/json") luci.http.prepare_content("application/json")

View File

@ -5,6 +5,10 @@ local has_singbox = api.finded_com("singbox")
local has_xray = api.finded_com("xray") local has_xray = api.finded_com("xray")
local has_chnlist = api.fs.access("/usr/share/passwall/rules/chnlist") local has_chnlist = api.fs.access("/usr/share/passwall/rules/chnlist")
local port_validate = function(self, value, t)
return value:gsub("-", ":")
end
m = Map(appname) m = Map(appname)
local nodes_table = {} local nodes_table = {}
@ -141,6 +145,7 @@ o.default = "default"
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o:value("default", translate("Default")) o:value("default", translate("Default"))
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o.validate = port_validate
---- UDP No Redir Ports ---- UDP No Redir Ports
o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports")) o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"))
@ -148,12 +153,14 @@ o.default = "default"
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o:value("default", translate("Default")) o:value("default", translate("Default"))
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o.validate = port_validate
---- TCP Proxy Drop Ports ---- TCP Proxy Drop Ports
o = s:option(Value, "tcp_proxy_drop_ports", translate("TCP Proxy Drop Ports")) o = s:option(Value, "tcp_proxy_drop_ports", translate("TCP Proxy Drop Ports"))
o.default = "default" o.default = "default"
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o:value("default", translate("Default")) o:value("default", translate("Default"))
o.validate = port_validate
---- UDP Proxy Drop Ports ---- UDP Proxy Drop Ports
o = s:option(Value, "udp_proxy_drop_ports", translate("UDP Proxy Drop Ports")) o = s:option(Value, "udp_proxy_drop_ports", translate("UDP Proxy Drop Ports"))
@ -161,6 +168,7 @@ o.default = "default"
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o:value("default", translate("Default")) o:value("default", translate("Default"))
o:value("80,443", translate("QUIC")) o:value("80,443", translate("QUIC"))
o.validate = port_validate
---- TCP Redir Ports ---- TCP Redir Ports
o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports")) o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports"))
@ -170,6 +178,7 @@ o:value("1:65535", translate("All"))
o:value("80,443", "80,443") o:value("80,443", "80,443")
o:value("80:65535", "80 " .. translate("or more")) o:value("80:65535", "80 " .. translate("or more"))
o:value("1:443", "443 " .. translate("or less")) o:value("1:443", "443 " .. translate("or less"))
o.validate = port_validate
---- UDP Redir Ports ---- UDP Redir Ports
o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports")) o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports"))
@ -177,6 +186,7 @@ o.default = "default"
o:value("default", translate("Default")) o:value("default", translate("Default"))
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o:value("53", "53") o:value("53", "53")
o.validate = port_validate
---- TCP Proxy Mode ---- TCP Proxy Mode
tcp_proxy_mode = s:option(ListValue, "tcp_proxy_mode", "TCP " .. translate("Proxy Mode")) tcp_proxy_mode = s:option(ListValue, "tcp_proxy_mode", "TCP " .. translate("Proxy Mode"))

View File

@ -49,7 +49,7 @@ o:depends("balancing_enable", true)
o = s:option(ListValue, "health_check_type", translate("Health Check Type")) o = s:option(ListValue, "health_check_type", translate("Health Check Type"))
o.default = "passwall_logic" o.default = "passwall_logic"
o:value("tcp", "TCP") o:value("tcp", "TCP")
o:value("passwall_logic", translate("Availability test") .. string.format("(passwall %s)", translate("Inner implement"))) o:value("passwall_logic", translate("URL Test") .. string.format("(passwall %s)", translate("Inner implement")))
o:depends("balancing_enable", true) o:depends("balancing_enable", true)
---- Health Check Inter ---- Health Check Inter
@ -60,7 +60,7 @@ o:depends("balancing_enable", true)
o = s:option(DummyValue, "health_check_tips", " ") o = s:option(DummyValue, "health_check_tips", " ")
o.rawhtml = true o.rawhtml = true
o.cfgvalue = function(t, n) o.cfgvalue = function(t, n)
return string.format('<span style="color: red">%s</span>', translate("When the availability 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.")) 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 end
o:depends("health_check_type", "passwall_logic") o:depends("health_check_type", "passwall_logic")

View File

@ -9,15 +9,19 @@ m = Map(appname)
s = m:section(TypedSection, "global_other") s = m:section(TypedSection, "global_other")
s.anonymous = true s.anonymous = true
o = s:option(MultiValue, "nodes_ping", " ") o = s:option(ListValue, "auto_detection_time", translate("Automatic detection delay"))
o:value("auto_ping", translate("Auto Ping"), translate("This will automatically ping the node for latency")) o:value("0", translate("Close"))
o:value("tcping", translate("Tcping"), translate("This will use tcping replace ping detection of node")) o:value("icmp", "Ping")
o:value("info", translate("Show server address and port"), translate("Show server address and port")) o:value("tcping", "TCP Ping")
o = s:option(Flag, "show_node_info", translate("Show server address and port"))
o.default = "0"
-- [[ Add the node via the link ]]-- -- [[ Add the node via the link ]]--
s:append(Template(appname .. "/node_list/link_add_node")) s:append(Template(appname .. "/node_list/link_add_node"))
local nodes_ping = m:get("@global_other[0]", "nodes_ping") or "" local auto_detection_time = m:get("@global_other[0]", "auto_detection_time") or "0"
local show_node_info = m:get("@global_other[0]", "show_node_info") or "0"
-- [[ Node List ]]-- -- [[ Node List ]]--
s = m:section(TypedSection, "nodes") s = m:section(TypedSection, "nodes")
@ -113,7 +117,7 @@ o.cfgvalue = function(t, n)
local port = m:get(n, "port") or "" local port = m:get(n, "port") or ""
str = str .. translate(type) .. "" .. remarks str = str .. translate(type) .. "" .. remarks
if address ~= "" and port ~= "" then if address ~= "" and port ~= "" then
if nodes_ping:find("info") then if show_node_info == "1" then
if datatypes.ip6addr(address) then if datatypes.ip6addr(address) then
str = str .. string.format("[%s]:%s", address, port) str = str .. string.format("[%s]:%s", address, port)
else else
@ -127,23 +131,38 @@ o.cfgvalue = function(t, n)
end end
---- Ping ---- Ping
o = s:option(DummyValue, "ping") o = s:option(DummyValue, "ping", "Ping")
o.width = "8%" o.width = "8%"
o.rawhtml = true o.rawhtml = true
o.cfgvalue = function(t, n) o.cfgvalue = function(t, n)
local result = "---" local result = "---"
if not nodes_ping:find("auto_ping") then if auto_detection_time ~= "icmp" then
result = string.format('<span class="ping"><a href="javascript:void(0)" onclick="javascript:ping_node(\'%s\',this)">Ping</a></span>', n) result = string.format('<span class="ping"><a href="javascript:void(0)" onclick="javascript:ping_node(\'%s\', this, \'icmp\')">%s</a></span>', n, translate("Test"))
else else
result = string.format('<span class="ping_value" cbiid="%s">---</span>', n) result = string.format('<span class="ping_value" cbiid="%s">---</span>', n)
end end
return result return result
end end
o = s:option(DummyValue, "_url_test") ---- TCP Ping
o = s:option(DummyValue, "tcping", "TCPing")
o.width = "8%"
o.rawhtml = true o.rawhtml = true
o.cfgvalue = function(t, n) o.cfgvalue = function(t, n)
return string.format('<input type="button" class="cbi-button" value="%s" onclick="javascript:urltest_node(\'%s\',this)"', translate("Availability test"), n) local result = "---"
if auto_detection_time ~= "tcping" then
result = string.format('<span class="ping"><a href="javascript:void(0)" onclick="javascript:ping_node(\'%s\', this, \'tcping\')">%s</a></span>', n, translate("Test"))
else
result = string.format('<span class="tcping_value" cbiid="%s">---</span>', n)
end
return result
end
o = s:option(DummyValue, "_url_test", translate("URL Test"))
o.width = "8%"
o.rawhtml = true
o.cfgvalue = function(t, n)
return string.format('<span class="ping"><a href="javascript:void(0)" onclick="javascript:urltest_node(\'%s\', this)">%s</a></span>', n, translate("Test"))
end end
m:append(Template(appname .. "/node_list/node_list")) m:append(Template(appname .. "/node_list/node_list"))

View File

@ -6,6 +6,10 @@ local has_xray = api.finded_com("xray")
local has_fw3 = api.is_finded("fw3") local has_fw3 = api.is_finded("fw3")
local has_fw4 = api.is_finded("fw4") local has_fw4 = api.is_finded("fw4")
local port_validate = function(self, value, t)
return value:gsub("-", ":")
end
m = Map(appname) m = Map(appname)
-- [[ Delay Settings ]]-- -- [[ Delay Settings ]]--
@ -63,6 +67,7 @@ o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports"))
o.default = "disable" o.default = "disable"
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o.validate = port_validate
---- UDP No Redir Ports ---- UDP No Redir Ports
o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"), o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"),
@ -72,17 +77,20 @@ o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"),
o.default = "disable" o.default = "disable"
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o.validate = port_validate
---- TCP Proxy Drop Ports ---- TCP Proxy Drop Ports
o = s:option(Value, "tcp_proxy_drop_ports", translate("TCP Proxy Drop Ports")) o = s:option(Value, "tcp_proxy_drop_ports", translate("TCP Proxy Drop Ports"))
o.default = "disable" o.default = "disable"
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o.validate = port_validate
---- UDP Proxy Drop Ports ---- UDP Proxy Drop Ports
o = s:option(Value, "udp_proxy_drop_ports", translate("UDP Proxy Drop Ports")) o = s:option(Value, "udp_proxy_drop_ports", translate("UDP Proxy Drop Ports"))
o.default = "443" o.default = "443"
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o:value("443", translate("QUIC")) o:value("443", translate("QUIC"))
o.validate = port_validate
---- TCP Redir Ports ---- TCP Redir Ports
o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports")) o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports"))
@ -90,12 +98,14 @@ o.default = "22,25,53,143,465,587,853,993,995,80,443"
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o:value("22,25,53,143,465,587,853,993,995,80,443", translate("Common Use")) o:value("22,25,53,143,465,587,853,993,995,80,443", translate("Common Use"))
o:value("80,443", translate("Only Web")) o:value("80,443", translate("Only Web"))
o.validate = port_validate
---- UDP Redir Ports ---- UDP Redir Ports
o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports")) o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports"))
o.default = "1:65535" o.default = "1:65535"
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o:value("53", "DNS") o:value("53", "DNS")
o.validate = port_validate
---- Use nftables ---- Use nftables
o = s:option(ListValue, "use_nft", translate("Firewall tools")) o = s:option(ListValue, "use_nft", translate("Firewall tools"))

View File

@ -41,7 +41,7 @@ o:value("trojan", translate("Trojan"))
o:value("wireguard", translate("WireGuard")) o:value("wireguard", translate("WireGuard"))
o:value("_balancing", translate("Balancing")) o:value("_balancing", translate("Balancing"))
o:value("_shunt", translate("Shunt")) o:value("_shunt", translate("Shunt"))
o:value("_iface", translate("Custom Interface") .. " (Only Support Xray)") o:value("_iface", translate("Custom Interface"))
o = s:option(Value, option_name("iface"), translate("Interface")) o = s:option(Value, option_name("iface"), translate("Interface"))
o.default = "eth1" o.default = "eth1"

View File

@ -58,7 +58,7 @@ if singbox_tags:find("with_quic") then
o:value("hysteria2", "Hysteria2") o:value("hysteria2", "Hysteria2")
end end
o:value("_shunt", translate("Shunt")) o:value("_shunt", translate("Shunt"))
o:value("_iface", translate("Custom Interface") .. " (Only Support Xray)") o:value("_iface", translate("Custom Interface"))
o = s:option(Value, option_name("iface"), translate("Interface")) o = s:option(Value, option_name("iface"), translate("Interface"))
o.default = "eth1" o.default = "eth1"

View File

@ -345,7 +345,7 @@ o = s:option(ListValue, option_name("outbound_node"), translate("outbound node")
o:value("nil", translate("Close")) o:value("nil", translate("Close"))
o:value("_socks", translate("Custom Socks")) o:value("_socks", translate("Custom Socks"))
o:value("_http", translate("Custom HTTP")) o:value("_http", translate("Custom HTTP"))
o:value("_iface", translate("Custom Interface") .. " (Only Support Xray)") o:value("_iface", translate("Custom Interface"))
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
o.default = "nil" o.default = "nil"

View File

@ -307,7 +307,7 @@ function get_domain_from_url(url)
end end
function get_valid_nodes() function get_valid_nodes()
local nodes_ping = uci_get_type("global_other", "nodes_ping") or "" local show_node_info = uci_get_type("global_other", "show_node_info") or "0"
local nodes = {} local nodes = {}
uci:foreach(appname, "nodes", function(e) uci:foreach(appname, "nodes", function(e)
e.id = e[".name"] e.id = e[".name"]
@ -334,7 +334,7 @@ function get_valid_nodes()
end end
if is_ipv6(address) then address = get_ipv6_full(address) end if is_ipv6(address) then address = get_ipv6_full(address) end
e["remark"] = "%s[%s]" % {type, e.remarks} e["remark"] = "%s[%s]" % {type, e.remarks}
if nodes_ping:find("info") then if show_node_info == "1" then
e["remark"] = "%s[%s] %s:%s" % {type, e.remarks, address, e.port} e["remark"] = "%s[%s] %s:%s" % {type, e.remarks, address, e.port}
end end
e.node_type = "normal" e.node_type = "normal"

View File

@ -48,9 +48,8 @@ local api = require "luci.passwall.api"
function add_node() { function add_node() {
var nodes_link = document.getElementById("nodes_link").value; var nodes_link = document.getElementById("nodes_link").value;
if (nodes_link.trim() != "") { if (nodes_link.trim() != "") {
var supports = "ss ssr vmess vless trojan trojan-go hysteria"; var s = nodes_link.split('://');
var itype = nodes_link.split('://')[0]; if (s.length > 1) {
if (itype.trim() != "" && supports.indexOf(itype) >= 0) {
ajax_add_node(nodes_link); ajax_add_node(nodes_link);
} }
else { else {
@ -81,9 +80,10 @@ local api = require "luci.passwall.api"
<div id="add_link_div"> <div id="add_link_div">
<div class="cbi-value"> <div class="cbi-value">
<label class="cbi-value-title"><%:SS/SSR/Vmess/VLESS/Trojan/Hysteria Link%></label> <label class="cbi-value-title"><%:Share Link%></label>
<div class="cbi-value-field"> <div class="cbi-value-field">
<textarea id="nodes_link" rows="5" cols="50"></textarea> <p><textarea id="nodes_link" rows="5" cols="50"></textarea></p>
<font color="red"><%:Not a subscription link!!!%></font>
</div> </div>
</div> </div>
<div class="cbi-value"> <div class="cbi-value">
@ -103,6 +103,8 @@ local api = require "luci.passwall.api"
<input class="btn cbi-button cbi-button-remove" type="button" onclick="delete_select_nodes()" value="<%:Delete select nodes%>" /> <input class="btn cbi-button cbi-button-remove" type="button" onclick="delete_select_nodes()" value="<%:Delete select nodes%>" />
<input class="btn cbi-button" type="button" onclick="checked_all_node(this)" value="<%:Select all%>" /> <input class="btn cbi-button" type="button" onclick="checked_all_node(this)" value="<%:Select all%>" />
<input class="btn cbi-button cbi-button-apply" type="submit" name="cbi.apply" value="<%:Save & Apply%>" /> <input class="btn cbi-button cbi-button-apply" type="submit" name="cbi.apply" value="<%:Save & Apply%>" />
<input class="btn cbi-button cbi-button-save" type="submit" name="cbi.save" value="<%:Save%>" />
<input class="btn cbi-button cbi-button-reset" type="button" value="<%:Reset%>" onclick="location.href='<%=REQUEST_URI%>'" />
<div id="div_node_count"></div> <div id="div_node_count"></div>
</div> </div>
</div> </div>

View File

@ -36,6 +36,8 @@ table td, .table .td {
<script type="text/javascript"> <script type="text/javascript">
//<![CDATA[ //<![CDATA[
let auto_detection_time = "<%=api.uci_get_type("global_other", "auto_detection_time", "0")%>"
var node_list = {}; var node_list = {};
var node_count = 0; var node_count = 0;
@ -229,8 +231,8 @@ table td, .table .td {
function urltest_node(cbi_id, dom) { function urltest_node(cbi_id, dom) {
if (cbi_id != null) { if (cbi_id != null) {
dom.disabled = true; dom.onclick = null
dom.value = "<%:Check...%>"; dom.innerText = "<%:Check...%>";
XHR.get('<%=api.url("urltest_node")%>', { XHR.get('<%=api.url("urltest_node")%>', {
id: cbi_id id: cbi_id
}, },
@ -241,6 +243,7 @@ table td, .table .td {
} else { } else {
var color = "red"; var color = "red";
var use_time = result.use_time; var use_time = result.use_time;
use_time = parseInt(use_time) + 1;
if (use_time < 1000) { if (use_time < 1000) {
color = "green"; color = "green";
} else if (use_time < 2000) { } else if (use_time < 2000) {
@ -248,20 +251,25 @@ table td, .table .td {
} else { } else {
color = "red"; color = "red";
} }
dom.outerHTML = "<font style='color:" + color + "'>" + result.use_time + " ms" + "</font>"; dom.outerHTML = "<font style='color:" + color + "'>" + use_time + " ms" + "</font>";
} }
} else {
dom.outerHTML = "<font style='color:red'><%:Error%></font>";
} }
} }
); );
} }
} }
function ping_node(cbi_id, dom) { function ping_node(cbi_id, dom, type) {
var full = get_address_full(cbi_id); var full = get_address_full(cbi_id);
if (full != null) { if (full != null) {
dom.onclick = null
dom.innerText = "<%:Check...%>";
XHR.get('<%=api.url("ping_node")%>', { XHR.get('<%=api.url("ping_node")%>', {
address: full.address, address: full.address,
port: full.port port: full.port,
type: type
}, },
function(x, result) { function(x, result) {
if(x && x.status == 200) { if(x && x.status == 200) {
@ -281,132 +289,88 @@ table td, .table .td {
); );
} }
} }
/* 自动Ping */
var nodes = [];
const ping_value = document.getElementsByClassName('ping_value');
for (var i = 0; i < ping_value.length; i++) {
var cbi_id = ping_value[i].getAttribute("cbiid");
var full = get_address_full(cbi_id);
if (full != null) {
var flag = false;
//当有多个相同地址和端口时合在一起
for (var j = 0; j < nodes.length; j++) {
if (nodes[j].address == full.address && nodes[j].port == full.port) {
nodes[j].indexs = nodes[j].indexs + "," + i;
flag = true;
break;
}
}
if (flag)
continue;
nodes.push({
indexs: i + "",
address: full.address,
port: full.port
});
}
}
get_now_use_node(); get_now_use_node();
const _xhr = (index) => { /* 自动Ping */
return new Promise((res) => { if (auto_detection_time == "icmp" || auto_detection_time == "tcping") {
const dom = nodes[index]; var nodes = [];
if (!dom) res() const ping_value = document.getElementsByClassName(auto_detection_time == "tcping" ? 'tcping_value' : 'ping_value');
ajax.post('<%=api.url("ping_node")%>', { for (var i = 0; i < ping_value.length; i++) {
index: dom.indexs, var cbi_id = ping_value[i].getAttribute("cbiid");
address: dom.address, var full = get_address_full(cbi_id);
port: dom.port if (full != null) {
}, var flag = false;
function(x, result) { //当有多个相同地址和端口时合在一起
if (x && x.status == 200) { for (var j = 0; j < nodes.length; j++) {
var strs = dom.indexs.split(","); if (nodes[j].address == full.address && nodes[j].port == full.port) {
for (var i = 0; i < strs.length; i++) { nodes[j].indexs = nodes[j].indexs + "," + i;
if (result.ping == null || result.ping.trim() == "") { flag = true;
ping_value[strs[i]].innerHTML = "<font style='color:red'><%:Timeout%></font>"; break;
} else { }
var ping = parseInt(result.ping); }
if (ping < 100) if (flag)
ping_value[strs[i]].innerHTML = "<font style='color:green'>" + result.ping + " ms" + "</font>"; continue;
else if (ping < 200) nodes.push({
ping_value[strs[i]].innerHTML = "<font style='color:#fb9a05'>" + result.ping + " ms" + "</font>"; indexs: i + "",
else if (ping >= 200) address: full.address,
ping_value[strs[i]].innerHTML = "<font style='color:red'>" + result.ping + " ms" + "</font>"; port: full.port
});
}
}
const _xhr = (index) => {
return new Promise((res) => {
const dom = nodes[index];
if (!dom) res()
ajax.post('<%=api.url("ping_node")%>', {
index: dom.indexs,
address: dom.address,
port: dom.port,
type: auto_detection_time
},
function(x, result) {
if (x && x.status == 200) {
var strs = dom.indexs.split(",");
for (var i = 0; i < strs.length; i++) {
if (result.ping == null || result.ping.trim() == "") {
ping_value[strs[i]].innerHTML = "<font style='color:red'><%:Timeout%></font>";
} else {
var ping = parseInt(result.ping);
if (ping < 100)
ping_value[strs[i]].innerHTML = "<font style='color:green'>" + result.ping + " ms" + "</font>";
else if (ping < 200)
ping_value[strs[i]].innerHTML = "<font style='color:#fb9a05'>" + result.ping + " ms" + "</font>";
else if (ping >= 200)
ping_value[strs[i]].innerHTML = "<font style='color:red'>" + result.ping + " ms" + "</font>";
}
} }
} }
} res();
res(); },
}, 5000,
5000, function(x) {
function(x) { var strs = dom.indexs.split(",");
var strs = dom.indexs.split(","); for (var i = 0; i < strs.length; i++) {
for (var i = 0; i < strs.length; i++) {
ping_value[strs[i]].innerHTML = "<font style='color:red'><%:Timeout%></font>";
}
res();
}
);
})
}
let task = -1;
const thread = () => {
task = task + 1
if (nodes[task]) {
_xhr(task).then(thread);
}
}
for (let i = 0; i < 20; i++) {
thread()
}
/* 递归单请求方法
var index = 0;
function auto_ping() {
if (index >= nodes.length) {
return;
}
var indexs = nodes[index].indexs;
var address = nodes[index].address;
var port = nodes[index].port;
ajax.post('<%=api.url("ping_node")%>', {
index: indexs,
address: address,
port: port
},
function(x, result) {
if (x && x.status == 200) {
var strs = indexs.split(",");
for (var i = 0; i < strs.length; i++) {
if (result.ping == null || result.ping.trim() == "") {
ping_value[strs[i]].innerHTML = "<font style='color:red'><%:Timeout%></font>"; ping_value[strs[i]].innerHTML = "<font style='color:red'><%:Timeout%></font>";
} else {
var ping = parseInt(result.ping);
if (ping < 100)
ping_value[strs[i]].innerHTML = "<font style='color:green'>" + result.ping + " ms" + "</font>";
else if (ping < 200)
ping_value[strs[i]].innerHTML = "<font style='color:#fb9a05'>" + result.ping + " ms" + "</font>";
else if (ping >= 200)
ping_value[strs[i]].innerHTML = "<font style='color:red'>" + result.ping + " ms" + "</font>";
} }
res();
} }
} );
index++; })
return auto_ping(); }
},
function(x) { let task = -1;
var strs = indexs.split(","); const thread = () => {
for (var i = 0; i < strs.length; i++) { task = task + 1
ping_value[strs[i]].innerHTML = "<font style='color:red'><%:Timeout%></font>"; if (nodes[task]) {
} _xhr(task).then(thread);
index++; }
return auto_ping(); }
}, for (let i = 0; i < 20; i++) {
); thread()
}
} }
auto_ping();
*/
var edit_btn = document.getElementById("cbi-passwall-nodes").getElementsByClassName("cbi-button cbi-button-edit"); var edit_btn = document.getElementById("cbi-passwall-nodes").getElementsByClassName("cbi-button cbi-button-edit");
for (var i = 0; i < edit_btn.length; i++) { for (var i = 0; i < edit_btn.length; i++) {

View File

@ -298,8 +298,11 @@ msgstr "添加节点"
msgid "Add the node via the link" msgid "Add the node via the link"
msgstr "通过链接添加节点" msgstr "通过链接添加节点"
msgid "SS/SSR/Vmess/VLESS/Trojan/Hysteria Link" msgid "Share Link"
msgstr "SS/SSR/Vmess/VLESS/Trojan/Hysteria 链接" msgstr "分享链接"
msgid "Not a subscription link!!!"
msgstr "不是订阅链接!!!"
msgid "Please enter the correct link." msgid "Please enter the correct link."
msgstr "请输入正确的链接。" msgstr "请输入正确的链接。"
@ -550,26 +553,17 @@ msgstr "加密"
msgid "Latency" msgid "Latency"
msgstr "延迟" msgstr "延迟"
msgid "Show Add Mode" msgid "Automatic detection delay"
msgstr "显示添加方式" msgstr "自动检测延迟"
msgid "Show Group"
msgstr "显示组"
msgid "Group"
msgstr "组"
msgid "Auto Ping"
msgstr "自动Ping"
msgid "Concise display nodes"
msgstr "简洁显示节点"
msgid "Show server address and port" msgid "Show server address and port"
msgstr "显示服务器地址和端口" msgstr "显示服务器地址和端口"
msgid "Availability test" msgid "URL Test"
msgstr "可用性测试" msgstr "URL 测试"
msgid "Test"
msgstr "测试"
msgid "Node num" msgid "Node num"
msgstr "节点数量" msgstr "节点数量"
@ -751,8 +745,8 @@ msgstr "内置实现"
msgid "Health Check Inter" msgid "Health Check Inter"
msgstr "健康检查节点间隔时间" msgstr "健康检查节点间隔时间"
msgid "When the availability 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." msgid "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."
msgstr "当使用可用性测试时负载均衡节点将转换成Socks节点。下面的节点列表自定义时必须为Socks节点否则健康检查将无效。" msgstr "当使用URL测试时负载均衡节点将转换成Socks节点。下面的节点列表自定义时必须为Socks节点否则健康检查将无效。"
msgid "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." msgid "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."
msgstr "添加节点指定出口功能是为多WAN用户准备的。负载比重范围1-256。多个主服务器可以负载均衡备用只有在主服务器离线时才会启用可以设置多个组负载均衡端口相同则为一组。" msgstr "添加节点指定出口功能是为多WAN用户准备的。负载比重范围1-256。多个主服务器可以负载均衡备用只有在主服务器离线时才会启用可以设置多个组负载均衡端口相同则为一组。"

View File

@ -52,7 +52,8 @@ config global_singbox
option geosite_url 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.db' option geosite_url 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.db'
config global_other config global_other
option nodes_ping 'auto_ping tcping' option auto_detection_time 'tcping'
option show_node_info '0'
config global_rules config global_rules
option auto_update '0' option auto_update '0'