update 2026-10-31 18:07:25
No files matched your search
|
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 |
@@ -886,17 +886,17 @@ function read_rulelist()
|
||||
end
|
||||
|
||||
local backup_files = {
|
||||
"/etc/config/passwall",
|
||||
"/etc/config/passwall_server",
|
||||
"/etc/passwall/rules/block_host",
|
||||
"/etc/passwall/rules/block_ip",
|
||||
"/etc/passwall/rules/direct_host",
|
||||
"/etc/passwall/rules/direct_ip",
|
||||
"/etc/passwall/rules/proxy_host",
|
||||
"/etc/passwall/rules/proxy_ip",
|
||||
"/etc/passwall/rules/lanlist_ipv4",
|
||||
"/etc/passwall/rules/lanlist_ipv6",
|
||||
"/etc/passwall/rules/domains_excluded"
|
||||
"/etc/config/passwall",
|
||||
"/etc/config/passwall_server",
|
||||
"/etc/passwall/rules/block_host",
|
||||
"/etc/passwall/rules/block_ip",
|
||||
"/etc/passwall/rules/direct_host",
|
||||
"/etc/passwall/rules/direct_ip",
|
||||
"/etc/passwall/rules/proxy_host",
|
||||
"/etc/passwall/rules/proxy_ip",
|
||||
"/etc/passwall/rules/lanlist_ipv4",
|
||||
"/etc/passwall/rules/lanlist_ipv6",
|
||||
"/etc/passwall/rules/domains_excluded"
|
||||
}
|
||||
|
||||
function create_backup()
|
||||
|
||||
@@ -172,7 +172,7 @@ o.validate = port_validate
|
||||
---- UDP No Redir Ports
|
||||
local UDP_NO_REDIR_PORTS = m:get("@global_forwarding[0]", "udp_no_redir_ports")
|
||||
o = s:taboption("Proxy", Value, "udp_no_redir_ports", translate("UDP No Redir Ports"),
|
||||
"<font color='red'>" ..
|
||||
"<font color='red'>" ..
|
||||
translate("Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") ..
|
||||
"</font>")
|
||||
o:value("", translate("Use global config") .. "(" .. UDP_NO_REDIR_PORTS .. ")")
|
||||
|
||||
@@ -119,7 +119,7 @@ o.rawhtml = true
|
||||
o.cfgvalue = function(self, section)
|
||||
return string.format([[
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" onclick="ManualSubscribeAll()" value="%s" />]],
|
||||
translate("Manual subscription All"))
|
||||
translate("Manual subscription All"))
|
||||
end
|
||||
|
||||
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>")
|
||||
|
||||
@@ -68,9 +68,9 @@ o.validate = port_validate
|
||||
|
||||
---- UDP No Redir Ports
|
||||
o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"),
|
||||
"<font color='red'>" .. translate(
|
||||
"Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") ..
|
||||
"</font>")
|
||||
"<font color='red'>" .. translate(
|
||||
"Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") ..
|
||||
"</font>")
|
||||
o.default = "disable"
|
||||
o:value("disable", translate("No patterns are used"))
|
||||
o:value("1:65535", translate("All"))
|
||||
|
||||
@@ -18,7 +18,7 @@ s.type_name = type_name
|
||||
s.option_prefix = "socks_"
|
||||
api.set_type_cbi(s)
|
||||
|
||||
o = s:option(ListValue, "del_protocol", "¡¡") --ʼÖÕÒþ²Ø£¬ÓÃÓÚɾ³ý protocol
|
||||
o = s:option(ListValue, "del_protocol", " ") --始终隐藏,用于删除 protocol
|
||||
o:depends({ __hide = "1" })
|
||||
o.rewrite_option = "protocol"
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ if load_urltest_options then -- [[ URLTest Start ]]
|
||||
o = s:option(Flag, "urltest_interrupt_exist_connections", translate("Interrupt existing connections"))
|
||||
o:depends({ protocol = "_urltest" })
|
||||
o.default = "0"
|
||||
o.description = translate("Interrupt existing connections when the selected outbound has changed.")
|
||||
o.description = translate("Interrupt existing connections when the selected outbound has changed.")
|
||||
end -- [[ URLTest End ]]
|
||||
|
||||
if load_iface_options then -- [[ 自定义接口 Start ]]
|
||||
|
||||
@@ -2037,7 +2037,7 @@ function gen_config(var)
|
||||
table.insert(dns.servers, remote_server)
|
||||
|
||||
fakedns_tag = "remote_fakeip"
|
||||
if remote_dns_fake or inner_fakedns == "1" then
|
||||
if remote_dns_fake or inner_fakedns == "1" then
|
||||
table.insert(dns.servers, {
|
||||
tag = fakedns_tag,
|
||||
type = "fakeip",
|
||||
@@ -2178,7 +2178,7 @@ function gen_config(var)
|
||||
local remote_dns_server = api.clone(remote_server)
|
||||
remote_dns_server.tag = value.shunt_tag
|
||||
local is_local = (remote_server.address and api.is_local_ip(remote_server.address)) or
|
||||
(remote_server.server and api.is_local_ip(remote_server.server)) --dns为本地ip,不走代理
|
||||
(remote_server.server and api.is_local_ip(remote_server.server)) --dns为本地ip,不走代理
|
||||
remote_dns_server.detour = is_local and "direct" or value.outboundTag
|
||||
table.insert(dns.servers, remote_dns_server)
|
||||
dns_rule.server = remote_dns_server.tag
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
return function(colorStr) {
|
||||
if (!colorStr)
|
||||
return null;
|
||||
return null;
|
||||
ctx.clearRect(0, 0, 1, 1);
|
||||
// 2. Apply the color
|
||||
ctx.fillStyle = colorStr;
|
||||
|
||||
@@ -169,7 +169,7 @@
|
||||
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
return function(colorStr) {
|
||||
if (!colorStr)
|
||||
return null;
|
||||
return null;
|
||||
ctx.clearRect(0, 0, 1, 1);
|
||||
// 2. Apply the color
|
||||
ctx.fillStyle = colorStr;
|
||||
|
||||
@@ -35,10 +35,10 @@ local groups = {}
|
||||
local group_order = {}
|
||||
for _, item in ipairs(values) do
|
||||
local g = item.group
|
||||
if not g or g == "" then
|
||||
g = translate("default")
|
||||
if not g or g == "" then
|
||||
g = translate("default")
|
||||
end
|
||||
if not groups[g] then
|
||||
if not groups[g] then
|
||||
groups[g] = {}
|
||||
table.insert(group_order, g)
|
||||
end
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
return function(colorStr) {
|
||||
if (!colorStr)
|
||||
return null;
|
||||
return null;
|
||||
ctx.clearRect(0, 0, 1, 1);
|
||||
// 2. Apply the color
|
||||
ctx.fillStyle = colorStr;
|
||||
@@ -258,7 +258,7 @@
|
||||
const keyword = searchInput.value.trim().toLowerCase();
|
||||
const isSearching = keyword.length > 0;
|
||||
// 当前实例下的所有 checkbox
|
||||
const cbs = isSearching
|
||||
const cbs = isSearching
|
||||
? Array.from(nodeList.querySelectorAll("input[type=checkbox]")).filter(cb => cb.closest("li").style.display !== "none")
|
||||
: nodeList.querySelectorAll("input[type=checkbox]");
|
||||
let checked = 0;
|
||||
|
||||
@@ -137,7 +137,7 @@ local dropdown_data = {
|
||||
</select>
|
||||
</div>
|
||||
<!-- 隐藏 input(保存实际配置值) -->
|
||||
<input type="text" id="<%=cbid%>" name="<%=cbid%>" value="<%=current_key%>" data-update="change" style="display:none !important;" />
|
||||
<input type="text" id="<%=cbid%>" name="<%=cbid%>" value="<%=current_key%>" data-update="change" style="display:none !important;" />
|
||||
<!-- 模拟 ListValue 控件外观 -->
|
||||
<div class="cbi-input-value cbi-input-select v-dropdown-display" id="<%=cbid%>.display" tabindex="0">
|
||||
<span id="<%=cbid%>.label" class="v-dropdown-label" title="<%=pcdata(current_label)%>">
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
return function(colorStr) {
|
||||
if (!colorStr)
|
||||
return null;
|
||||
return null;
|
||||
ctx.clearRect(0, 0, 1, 1);
|
||||
// 2. Apply the color
|
||||
ctx.fillStyle = colorStr;
|
||||
|
||||
@@ -5,11 +5,11 @@ local appname = map.config
|
||||
local sid = "@global[0]"
|
||||
-%>
|
||||
<style>
|
||||
#cbi-<%=appname%>-socks .td.cbi-value-field > div {
|
||||
#cbi-<%=appname%>-socks .td.cbi-value-field > div {
|
||||
white-space: nowrap;
|
||||
}
|
||||
@media (max-width: 1152px) {
|
||||
#cbi-<%=appname%>-socks .td.cbi-value-field > div {
|
||||
#cbi-<%=appname%>-socks .td.cbi-value-field > div {
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
@@ -150,7 +150,7 @@ local sid = "@global[0]"
|
||||
html += '<a href="#" onclick="window.open(\'' + '<%=api.url("get_socks_log")%>?name=' + id.replace("cbi-<%=appname%>-", "") + '\', \'_blank\')"><%:Log%></a>';
|
||||
|
||||
node_select.insertAdjacentHTML("afterend",
|
||||
'<div class="node-actions" style="display:inline-flex; align-items:center; gap:4px; flex-wrap:wrap; margin-left:4px;">'
|
||||
'<div class="node-actions" style="display:inline-flex; align-items:center; gap:4px; flex-wrap:wrap; margin-left:4px;">'
|
||||
+ html + '</div>'
|
||||
);
|
||||
} catch(err) {
|
||||
|
||||
@@ -187,7 +187,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
//<![CDATA[
|
||||
var imgs = document.getElementsByTagName('img');
|
||||
|
||||
@@ -133,7 +133,7 @@ local has_old_geosite = fs.access("/tmp/bak_v2ray/geosite.dat")
|
||||
var checkBoxList = [];
|
||||
var len = domList.length;
|
||||
while(len--) {
|
||||
var dom = domList[len];
|
||||
var dom = domList[len];
|
||||
if(dom.type == 'checkbox' && dom.checked) {
|
||||
checkBoxList.push(dom.name);
|
||||
}
|
||||
@@ -162,7 +162,7 @@ local has_old_geosite = fs.access("/tmp/bak_v2ray/geosite.dat")
|
||||
var checkBoxList = [];
|
||||
var len = domList.length;
|
||||
while(len--) {
|
||||
var dom = domList[len];
|
||||
var dom = domList[len];
|
||||
if(dom.type == 'checkbox' && dom.checked) {
|
||||
if(type == 'geoip' && (dom.name === 'chnroute' || dom.name === 'chnroute6')) {
|
||||
checkBoxList.push(dom.name);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
if [ -e "/etc/config/ucitrack" ]; then
|
||||
uci -q batch <<-EOF
|
||||
delete ucitrack.@passwall[-1]
|
||||
delete ucitrack.@passwall[-1]
|
||||
add ucitrack passwall
|
||||
set ucitrack.@passwall[-1].init=passwall
|
||||
commit ucitrack
|
||||
|
||||
@@ -1088,7 +1088,7 @@ start_dns() {
|
||||
local ACL_RULE_DNSMASQ=0
|
||||
for acl_section in $(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do
|
||||
if [ "$(config_n_get $acl_section enabled)" = "1" ] && \
|
||||
[ "$(config_n_get $acl_section dns_shunt)" = "dnsmasq" ]; then
|
||||
[ "$(config_n_get $acl_section dns_shunt)" = "dnsmasq" ]; then
|
||||
ACL_RULE_DNSMASQ=1
|
||||
break
|
||||
fi
|
||||
@@ -1101,7 +1101,7 @@ start_dns() {
|
||||
china_ng_local_dns=${LOCAL_DNS}
|
||||
v2ray_local_dns="direct_dns_udp_server=${LOCAL_DNS}"
|
||||
;;
|
||||
tcp)
|
||||
tcp)
|
||||
local DIRECT_DNS=$(normalize_dns "$(config_n_get @global[0] direct_dns 223.5.5.5:53)")
|
||||
china_ng_local_dns="tcp://${DIRECT_DNS}"
|
||||
v2ray_local_dns="direct_dns_tcp_server=${DIRECT_DNS}"
|
||||
|
||||
@@ -625,7 +625,7 @@ local function encode_node(node)
|
||||
end
|
||||
|
||||
function parseClashNode(raw, remark)
|
||||
if not raw then return "" end
|
||||
if not raw then return "" end
|
||||
domain_redir = {}
|
||||
local ok, lyaml = pcall(require, "lyaml")
|
||||
if not ok then return raw end
|
||||
|
||||
@@ -605,7 +605,7 @@ if CHNLIST == "proxy" then DEFAULT_TAG = "chn" end
|
||||
--全局模式,默认使用远程DNS
|
||||
if only_global then
|
||||
DEFAULT_TAG = "gfw"
|
||||
if NO_IPV6_TRUST == "1" and not IS_SHUNT_NODE then
|
||||
if NO_IPV6_TRUST == "1" and not IS_SHUNT_NODE then
|
||||
table.insert(config_lines, "no-ipv6")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -761,7 +761,7 @@ function add_rule(var)
|
||||
server_out:close()
|
||||
ipset_out:close()
|
||||
end
|
||||
|
||||
|
||||
if not GEO_SUCCESS then new_text = "" end
|
||||
local f_out = io.open(CACHE_TEXT_FILE, "a")
|
||||
f_out:write(new_text)
|
||||
|
||||
@@ -172,9 +172,7 @@ local auto_config_lines = {}
|
||||
-- 直连规则显式覆盖远程兜底的缓存、IPv6、测速和双栈优选设置。
|
||||
local DIRECT_RULE_OPTIONS = " -enable-cache -address -6 -speed-check-mode ping,tcp:80,tcp:443 -response-mode first-ping -d yes"
|
||||
--设置默认 DNS 分组(兜底组),全局代理模式仍使用远程组。
|
||||
local DEFAULT_DNS_GROUP = (USE_DEFAULT_DNS == "direct" and "direct") or
|
||||
(USE_DEFAULT_DNS == "remote" and "proxy") or
|
||||
(USE_DEFAULT_DNS == "auto" and AUTO_GROUP)
|
||||
local DEFAULT_DNS_GROUP = (USE_DEFAULT_DNS == "direct" and "direct") or (USE_DEFAULT_DNS == "remote" and "proxy") or (USE_DEFAULT_DNS == "auto" and AUTO_GROUP)
|
||||
local only_global = (DEFAULT_PROXY_MODE == "proxy" and CHN_LIST == "0" and USE_GFW_LIST == "0") and 1
|
||||
if only_global == 1 then
|
||||
DEFAULT_DNS_GROUP = "proxy"
|
||||
|
||||
@@ -817,7 +817,7 @@ filter_node() {
|
||||
local address=$(config_n_get "$node" address)
|
||||
local port=$(config_n_get "$node" port)
|
||||
local hop=$(config_n_get "$node" hysteria2_hop)
|
||||
[ -n "$hop" ] && port="${port:+$port,}$hop"
|
||||
[ -n "$hop" ] && port="${port:+$port,}$hop"
|
||||
[ -z "$address" ] && return 1
|
||||
echo "$address" | grep -Eq "$EXCLUDE_VPSIP" && return 1
|
||||
[ -z "$port" ] && return 1
|
||||
|
||||
@@ -197,20 +197,20 @@ insert_nftset() {
|
||||
RS = "[ \t\n\r]+"
|
||||
ORS = ""
|
||||
}
|
||||
$0 != "" {
|
||||
if (!first) {
|
||||
printf "add element %s %s { \n", t, n
|
||||
$0 != "" {
|
||||
if (!first) {
|
||||
printf "add element %s %s { \n", t, n
|
||||
first = 1
|
||||
} else {
|
||||
print ",\n"
|
||||
}
|
||||
printf " %s", $0
|
||||
}
|
||||
END {
|
||||
if (first) {
|
||||
print "\n }\n"
|
||||
}
|
||||
}' | nft -f -
|
||||
} else {
|
||||
print ",\n"
|
||||
}
|
||||
printf " %s", $0
|
||||
}
|
||||
END {
|
||||
if (first) {
|
||||
print "\n }\n"
|
||||
}
|
||||
}' | nft -f -
|
||||
}
|
||||
|
||||
gen_nftset() {
|
||||
@@ -300,7 +300,7 @@ load_acl() {
|
||||
use_shunt_node=0
|
||||
[ -n "$node" ] && [ "$(config_n_get $node protocol)" = "_shunt" ] && use_shunt_node=1
|
||||
|
||||
[ "${use_global_config}" = "1" ] && {
|
||||
[ "${use_global_config}" = "1" ] && {
|
||||
if [ "$(config_get_type $NODE)" = "socks" ]; then
|
||||
node_remark="Socks 配置($(config_n_get $NODE port) 端口)"
|
||||
else
|
||||
@@ -856,7 +856,7 @@ filter_node() {
|
||||
local address=$(config_n_get "$node" address)
|
||||
local port=$(config_n_get "$node" port)
|
||||
local hop=$(config_n_get "$node" hysteria2_hop)
|
||||
[ -n "$hop" ] && port="${port:+$port,}$hop"
|
||||
[ -n "$hop" ] && port="${port:+$port,}$hop"
|
||||
[ -z "$address" ] && return 1
|
||||
echo "$address" | grep -Eq "$EXCLUDE_VPSIP" && return 1
|
||||
[ -z "$port" ] && return 1
|
||||
@@ -954,7 +954,7 @@ add_firewall_rule() {
|
||||
add_script_mwan3
|
||||
mwan3_start
|
||||
set_tproxy_sysctl
|
||||
gen_nftset $NFTSET_WAN ipv4_addr 0
|
||||
gen_nftset $NFTSET_WAN ipv4_addr 0
|
||||
gen_nftset $NFTSET_VPS ipv4_addr 0
|
||||
gen_nftset $NFTSET_GFW ipv4_addr "2d"
|
||||
gen_nftset $NFTSET_LOCAL ipv4_addr 0
|
||||
@@ -976,7 +976,7 @@ add_firewall_rule() {
|
||||
gen_nftset $NFTSET_SHUNT ipv4_addr "2d"
|
||||
gen_nftset $NFTSET_SHUNT_STATIC ipv4_addr 0
|
||||
|
||||
gen_nftset $NFTSET_WAN6 ipv6_addr 0
|
||||
gen_nftset $NFTSET_WAN6 ipv6_addr 0
|
||||
gen_nftset $NFTSET_VPS6 ipv6_addr 0
|
||||
gen_nftset $NFTSET_GFW6 ipv6_addr "2d"
|
||||
gen_nftset $NFTSET_LOCAL6 ipv6_addr 0
|
||||
@@ -1502,7 +1502,7 @@ add_firewall_rule() {
|
||||
|
||||
del_firewall_rule() {
|
||||
for nft in "dstnat" "srcnat" "nat_output" "mangle_prerouting" "mangle_output"; do
|
||||
local handles=$(nft -a list chain $NFTABLE_NAME ${nft} 2>/dev/null | grep -E "PSW_" | awk -F '# handle ' '{print$2}')
|
||||
local handles=$(nft -a list chain $NFTABLE_NAME ${nft} 2>/dev/null | grep -E "PSW_" | awk -F '# handle ' '{print$2}')
|
||||
for handle in $handles; do
|
||||
nft delete rule $NFTABLE_NAME ${nft} handle ${handle} 2>/dev/null
|
||||
done
|
||||
|
||||
@@ -345,7 +345,7 @@ local function extract_domain(s)
|
||||
local last_dot = nil
|
||||
for i = 1, len do
|
||||
local b = s:byte(i)
|
||||
-- 允许的域名字符:a-zA-Z0-9.-
|
||||
-- 允许的域名字符:a-zA-Z0-9.-
|
||||
if (b >= 48 and b <= 57) or (b >= 65 and b <= 90) or (b >= 97 and b <= 122) or b == 45 or b == 46 then
|
||||
if not start then start = i end
|
||||
if b == 46 then last_dot = i end
|
||||
|
||||
@@ -608,7 +608,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
result.protocol = hostInfo[#hostInfo-3]
|
||||
result.method = hostInfo[#hostInfo-2]
|
||||
result.obfs = hostInfo[#hostInfo-1]
|
||||
result.password = base64Decode(hostInfo[#hostInfo])
|
||||
result.password = base64Decode(hostInfo[#hostInfo])
|
||||
local params = {}
|
||||
for _, v in pairs(split(dat[2], '&')) do
|
||||
local s = v:find("=", 1, true)
|
||||
@@ -695,7 +695,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
|
||||
if not info.net then info.net = "tcp" end
|
||||
info.net = string.lower(info.net)
|
||||
if result.type == "sing-box" and info.net == "raw" then
|
||||
if result.type == "sing-box" and info.net == "raw" then
|
||||
info.net = "tcp"
|
||||
elseif result.type == "Xray" and info.net == "tcp" then
|
||||
info.net = "raw"
|
||||
@@ -962,7 +962,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
|
||||
if params.type then
|
||||
params.type = string.lower(params.type)
|
||||
if result.type == "sing-box" and params.type == "raw" then
|
||||
if result.type == "sing-box" and params.type == "raw" then
|
||||
params.type = "tcp"
|
||||
elseif result.type == "Xray" and params.type == "tcp" then
|
||||
params.type = "raw"
|
||||
@@ -1175,7 +1175,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
|
||||
if not params.type then params.type = "tcp" end
|
||||
params.type = string.lower(params.type)
|
||||
if result.type == "sing-box" and params.type == "raw" then
|
||||
if result.type == "sing-box" and params.type == "raw" then
|
||||
params.type = "tcp"
|
||||
elseif result.type == "Xray" and params.type == "tcp" then
|
||||
params.type = "raw"
|
||||
@@ -1302,7 +1302,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
if ({ xhttp=true, kcp=true, mkcp=true })[params.type] and result.type ~= "Xray" and has_xray then
|
||||
result.type = "Xray"
|
||||
end
|
||||
if result.type == "sing-box" and params.type == "raw" then
|
||||
if result.type == "sing-box" and params.type == "raw" then
|
||||
params.type = "tcp"
|
||||
elseif result.type == "Xray" and params.type == "tcp" then
|
||||
params.type = "raw"
|
||||
@@ -2117,7 +2117,7 @@ local function update_node(manual)
|
||||
uci_set(cfgid, "chain_proxy", "3")
|
||||
uci_set(cfgid, "outbound_iface", outbound_iface_group)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -114,7 +114,7 @@ o.rawhtml = true
|
||||
o.cfgvalue = function(self, section)
|
||||
return string.format([[
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" onclick="ManualSubscribeAll()" value="%s" />]],
|
||||
translate("Manual subscription All"))
|
||||
translate("Manual subscription All"))
|
||||
end
|
||||
|
||||
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>")
|
||||
|
||||
@@ -201,7 +201,7 @@ if has_xray then
|
||||
|
||||
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
|
||||
|
||||
|
||||
o = s_xray:option(ListValue, "fragment_packets", translate("Fragment Packets"), translate(" \"1-3\" is for segmentation at TCP layer, applying to the beginning 1 to 3 data writes by the client. \"tlshello\" is for TLS client hello packet fragmentation."))
|
||||
o.default = "tlshello"
|
||||
o:value("tlshello", "tlshello")
|
||||
|
||||
@@ -19,13 +19,13 @@ m.description = (m.description or "") .. [[
|
||||
<style>
|
||||
/* Scope to passwall2 CBI fields so it won't leak elsewhere */
|
||||
div[id^="cbid.passwall2."] .cbi-value-field {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1em;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1em;
|
||||
}
|
||||
div[id^="cbid.passwall2."] .cbi-checkbox {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
]]
|
||||
|
||||
@@ -160,7 +160,7 @@ o = s:option(Value, "autoswitch_retry_num", translate("Timeout retry num"))
|
||||
o.datatype = "min(1)"
|
||||
o.default = 1
|
||||
o:depends("enable_autoswitch", true)
|
||||
|
||||
|
||||
o = s:option(Flag, "autoswitch_restore_switch", translate("Restore Switch"), translate("When detects main node is available, switch back to the main node."))
|
||||
o:depends("enable_autoswitch", true)
|
||||
|
||||
|
||||
@@ -715,7 +715,7 @@ if singbox_tags:find("with_utls") then
|
||||
|
||||
o = s:option(Value, "reality_publicKey", translate("Public Key"))
|
||||
o:depends({ reality = true })
|
||||
|
||||
|
||||
o = s:option(Value, "reality_shortId", translate("Short Id"))
|
||||
o:depends({ reality = true })
|
||||
end
|
||||
|
||||
@@ -304,10 +304,10 @@ if singbox_tags:find("with_utls") then
|
||||
o:depends({ protocol = "vless", tls = true })
|
||||
o:depends({ protocol = "trojan", tls = true })
|
||||
o:depends({ protocol = "anytls", tls = true })
|
||||
|
||||
|
||||
o = s:option(Value, "reality_private_key", translate("Private Key"))
|
||||
o:depends({ reality = true })
|
||||
|
||||
|
||||
o = s:option(Value, "reality_shortId", translate("Short Id"))
|
||||
o:depends({ reality = true })
|
||||
|
||||
|
||||
@@ -536,7 +536,7 @@ function strToTable(str)
|
||||
if str == nil or type(str) ~= "string" then
|
||||
return {}
|
||||
end
|
||||
|
||||
|
||||
return loadstring("return " .. str)()
|
||||
end
|
||||
|
||||
@@ -922,7 +922,7 @@ function clone(org)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local res = {}
|
||||
copy(org, res)
|
||||
return res
|
||||
|
||||
@@ -78,7 +78,7 @@ function gen_config(var)
|
||||
fast_open = (node.tcp_fast_open and node.tcp_fast_open == "1") and true or false,
|
||||
reuse_port = true
|
||||
}
|
||||
|
||||
|
||||
if node.type == "SSR" then
|
||||
config.protocol = node.protocol
|
||||
config.protocol_param = node.protocol_param
|
||||
@@ -115,7 +115,7 @@ function gen_config(var)
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return jsonc.stringify(config, 1)
|
||||
end
|
||||
|
||||
|
||||
@@ -1730,7 +1730,7 @@ function gen_config(var)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local rule = {
|
||||
action = "route",
|
||||
inbound = inboundTag,
|
||||
@@ -2326,7 +2326,7 @@ function gen_config(var)
|
||||
table.insert(route.rule_set, v)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if inbounds or outbounds then
|
||||
local config = {
|
||||
log = {
|
||||
@@ -2468,7 +2468,7 @@ function gen_proto_config(var)
|
||||
}
|
||||
if outbound then table.insert(outbounds, outbound) end
|
||||
end
|
||||
|
||||
|
||||
local config = {
|
||||
log = {
|
||||
disabled = true,
|
||||
|
||||
@@ -115,7 +115,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
else
|
||||
dialer_proxy_tag = proxy_tag
|
||||
end
|
||||
|
||||
|
||||
if node.type == "Xray" then
|
||||
if node.tls and node.tls == "1" then
|
||||
node.stream_security = "tls"
|
||||
@@ -982,7 +982,7 @@ function gen_config(var)
|
||||
local routing = nil
|
||||
local observatory = nil
|
||||
local burstObservatory = nil
|
||||
local strategy = nil
|
||||
local strategy = nil
|
||||
local COMMON = {}
|
||||
|
||||
local CACHE_TEXT_FILE = CACHE_PATH .. "/cache_" .. flag .. ".txt"
|
||||
@@ -1253,7 +1253,7 @@ function gen_config(var)
|
||||
table.insert(rules, { inboundTag = { inbound_tag }, balancerTag = balancer_tag })
|
||||
return balancer_tag, loopback_outbound
|
||||
end
|
||||
|
||||
|
||||
function set_outbound_detour(node, outbound, outbounds_table)
|
||||
if not node or not outbound or not outbounds_table then return nil end
|
||||
local default_outTag = outbound.tag
|
||||
@@ -1684,7 +1684,7 @@ function gen_config(var)
|
||||
rules = {}
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
local dns_host = ""
|
||||
if flag == "global" then
|
||||
dns_host = api.uci_get_c("@global[0]", "dns_hosts") or ""
|
||||
@@ -1708,7 +1708,7 @@ function gen_config(var)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
local _remote_dns = {
|
||||
tag = remote_dns_tag,
|
||||
queryStrategy = (remote_dns_query_strategy and remote_dns_query_strategy ~= "") and remote_dns_query_strategy or "UseIPv4"
|
||||
@@ -1858,12 +1858,12 @@ function gen_config(var)
|
||||
outboundTag = "dns-out"
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
local default_dns_tag_name = remote_dns_tag
|
||||
if not COMMON.default_outbound_tag or COMMON.default_outbound_tag == "direct" then
|
||||
default_dns_tag_name = direct_dns_tag
|
||||
end
|
||||
|
||||
|
||||
if dns_servers and #dns_servers > 0 then
|
||||
-- Default DNS logic
|
||||
local default_dns_server = nil
|
||||
@@ -2064,7 +2064,7 @@ function gen_config(var)
|
||||
udp_inbound.settings.allowedNetwork = "udp"
|
||||
table.insert(inbounds, udp_inbound)
|
||||
end
|
||||
|
||||
|
||||
if inbounds or outbounds then
|
||||
local config = {
|
||||
env = (function()
|
||||
@@ -2138,7 +2138,7 @@ function gen_config(var)
|
||||
for index, value in ipairs(config.outbounds) do
|
||||
local s = value.settings
|
||||
if not value["_flag_proxy_tag"] and value["_id"] and s and not NO_RUN and
|
||||
((s.vnext and s.vnext[1] and s.vnext[1].address and s.vnext[1].port) or
|
||||
((s.vnext and s.vnext[1] and s.vnext[1].address and s.vnext[1].port) or
|
||||
(s.servers and s.servers[1] and s.servers[1].address and s.servers[1].port) or
|
||||
(s.peers and s.peers[1] and s.peers[1].endpoint) or
|
||||
(s.address and s.port)) then
|
||||
@@ -2168,7 +2168,7 @@ function gen_proto_config(var)
|
||||
local server_port = var["server_port"]
|
||||
local server_username = var["server_username"]
|
||||
local server_password = var["server_password"]
|
||||
|
||||
|
||||
local inbounds = {}
|
||||
local outbounds = {}
|
||||
local routing = nil
|
||||
@@ -2194,7 +2194,7 @@ function gen_proto_config(var)
|
||||
end
|
||||
table.insert(inbounds, inbound)
|
||||
end
|
||||
|
||||
|
||||
if local_http_address and local_http_port then
|
||||
local inbound = {
|
||||
listen = local_http_address,
|
||||
@@ -2214,7 +2214,7 @@ function gen_proto_config(var)
|
||||
end
|
||||
table.insert(inbounds, inbound)
|
||||
end
|
||||
|
||||
|
||||
if server_proto ~= "nil" and server_address ~= "nil" and server_port ~= "nil" then
|
||||
local outbound = {
|
||||
protocol = server_proto,
|
||||
@@ -2250,7 +2250,7 @@ function gen_proto_config(var)
|
||||
sockopt = {mark = 255}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
local config = {
|
||||
log = {
|
||||
loglevel = "warning"
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
return function(colorStr) {
|
||||
if (!colorStr)
|
||||
return null;
|
||||
return null;
|
||||
ctx.clearRect(0, 0, 1, 1);
|
||||
// 2. Apply the color
|
||||
ctx.fillStyle = colorStr;
|
||||
@@ -213,7 +213,7 @@
|
||||
if (!rgb) return 'unknown'; // Handle invalid colors
|
||||
// Calculate YIQ brightness (human eye perception)
|
||||
const brightness = ((rgb.r * 299) + (rgb.g * 587) + (rgb.b * 114)) / 1000;
|
||||
|
||||
|
||||
return brightness > 128 ? 'light' : 'dark';
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@
|
||||
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
return function(colorStr) {
|
||||
if (!colorStr)
|
||||
return null;
|
||||
return null;
|
||||
ctx.clearRect(0, 0, 1, 1);
|
||||
// 2. Apply the color
|
||||
ctx.fillStyle = colorStr;
|
||||
|
||||
@@ -35,10 +35,10 @@ local groups = {}
|
||||
local group_order = {}
|
||||
for _, item in ipairs(values) do
|
||||
local g = item.group
|
||||
if not g or g == "" then
|
||||
g = translate("default")
|
||||
if not g or g == "" then
|
||||
g = translate("default")
|
||||
end
|
||||
if not groups[g] then
|
||||
if not groups[g] then
|
||||
groups[g] = {}
|
||||
table.insert(group_order, g)
|
||||
end
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
return function(colorStr) {
|
||||
if (!colorStr)
|
||||
return null;
|
||||
return null;
|
||||
ctx.clearRect(0, 0, 1, 1);
|
||||
// 2. Apply the color
|
||||
ctx.fillStyle = colorStr;
|
||||
@@ -163,7 +163,7 @@
|
||||
if (!rgb) return 'unknown'; // Handle invalid colors
|
||||
// Calculate YIQ brightness (human eye perception)
|
||||
const brightness = ((rgb.r * 299) + (rgb.g * 587) + (rgb.b * 114)) / 1000;
|
||||
|
||||
|
||||
return brightness > 128 ? 'light' : 'dark';
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
const keyword = searchInput.value.trim().toLowerCase();
|
||||
const isSearching = keyword.length > 0;
|
||||
// 当前实例下的所有 checkbox
|
||||
const cbs = isSearching
|
||||
const cbs = isSearching
|
||||
? Array.from(nodeList.querySelectorAll("input[type=checkbox]")).filter(cb => cb.closest("li").style.display !== "none")
|
||||
: nodeList.querySelectorAll("input[type=checkbox]");
|
||||
let checked = 0;
|
||||
|
||||
@@ -137,7 +137,7 @@ local dropdown_data = {
|
||||
</select>
|
||||
</div>
|
||||
<!-- 隐藏 input(保存实际配置值) -->
|
||||
<input type="text" id="<%=cbid%>" name="<%=cbid%>" value="<%=current_key%>" data-update="change" style="display:none !important;" />
|
||||
<input type="text" id="<%=cbid%>" name="<%=cbid%>" value="<%=current_key%>" data-update="change" style="display:none !important;" />
|
||||
<!-- 模拟 ListValue 控件外观 -->
|
||||
<div class="cbi-input-value cbi-input-select v-dropdown-display" id="<%=cbid%>.display" tabindex="0">
|
||||
<span id="<%=cbid%>.label" class="v-dropdown-label" title="<%=pcdata(current_label)%>">
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
return function(colorStr) {
|
||||
if (!colorStr)
|
||||
return null;
|
||||
return null;
|
||||
ctx.clearRect(0, 0, 1, 1);
|
||||
// 2. Apply the color
|
||||
ctx.fillStyle = colorStr;
|
||||
|
||||
@@ -36,7 +36,7 @@ local appname = self.appname or map.config
|
||||
background-color: rgba(131, 191, 255, 0.7) !important;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 1152px) {
|
||||
#cbi-<%=appname%>-<%=sectiontype%> .cbi-section-table-titles {
|
||||
display: none !important;
|
||||
@@ -116,7 +116,7 @@ local appname = self.appname or map.config
|
||||
hiddenInput.value = changed ? newOrder.join(" ") : "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// hide lua luci version up/down
|
||||
function hideSortColumn(section) {
|
||||
var table = section.getElementsByTagName("table")[0];
|
||||
|
||||
@@ -153,7 +153,7 @@ local api = map.api
|
||||
if (confirm("<%: Are you sure you want to restore the client to default settings?%>")) {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open("GET",'<%= api.url("reset_config") %>', false);
|
||||
xhr.send();
|
||||
xhr.send();
|
||||
window.location.href = '<%= api.url("log") %>'
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
@@ -4,25 +4,25 @@ local api = map.api
|
||||
-%>
|
||||
<style>
|
||||
.dns-con {
|
||||
padding: 1rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
.faq-title {
|
||||
color: var(--primary);
|
||||
font-weight: bolder;
|
||||
margin-bottom: 0.5rem;
|
||||
display: inline-block;
|
||||
color: var(--primary);
|
||||
font-weight: bolder;
|
||||
margin-bottom: 0.5rem;
|
||||
display: inline-block;
|
||||
}
|
||||
.reset-title {
|
||||
color: var(--primary);
|
||||
font-weight: bolder;
|
||||
margin-bottom: 0.3rem;
|
||||
display: inline-block;
|
||||
margin-top: 1.2rem;
|
||||
text-decoration: underline;
|
||||
color: var(--primary);
|
||||
font-weight: bolder;
|
||||
margin-bottom: 0.3rem;
|
||||
display: inline-block;
|
||||
margin-top: 1.2rem;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.dns-item {
|
||||
margin-bottom: 0.8rem;
|
||||
line-height:1.2rem;
|
||||
margin-bottom: 0.8rem;
|
||||
line-height:1.2rem;
|
||||
}
|
||||
.dns-list {
|
||||
text-indent:1rem;
|
||||
@@ -50,13 +50,13 @@ local api = map.api
|
||||
var origin = window.location.origin;
|
||||
var hide_url = origin + "<%=api.url("hide")%>";
|
||||
var show_url = origin + "<%=api.url("show")%>";
|
||||
|
||||
|
||||
function hide(url) {
|
||||
if (confirm('<%:Are you sure to hide?%>') == true) {
|
||||
window.location.href = hide_url;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var dom = document.getElementById("faq_reset");
|
||||
if (dom) {
|
||||
var li = "";
|
||||
|
||||
@@ -5,11 +5,11 @@ local appname = map.config
|
||||
local sid = "@global[0]"
|
||||
-%>
|
||||
<style>
|
||||
#cbi-<%=appname%>-socks .td.cbi-value-field > div {
|
||||
#cbi-<%=appname%>-socks .td.cbi-value-field > div {
|
||||
white-space: nowrap;
|
||||
}
|
||||
@media (max-width: 1152px) {
|
||||
#cbi-<%=appname%>-socks .td.cbi-value-field > div {
|
||||
#cbi-<%=appname%>-socks .td.cbi-value-field > div {
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
@@ -162,7 +162,7 @@ local sid = "@global[0]"
|
||||
html += '<a href="#" onclick="window.open(\'' + '<%=api.url("get_socks_log")%>?name=' + id.replace("cbi-<%=appname%>-", "") + '\', \'_blank\')"><%:Log%></a>';
|
||||
|
||||
node_select.insertAdjacentHTML("afterend",
|
||||
'<div class="node-actions" style="display:inline-flex; align-items:center; gap:4px; flex-wrap:wrap; margin-left:4px;">'
|
||||
'<div class="node-actions" style="display:inline-flex; align-items:center; gap:4px; flex-wrap:wrap; margin-left:4px;">'
|
||||
+ html + '</div>'
|
||||
);
|
||||
} catch(err) {
|
||||
|
||||
@@ -54,7 +54,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
line-height: 1.8em;
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
|
||||
.check {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -73,7 +73,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
margin: 1rem 0rem 1rem 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.block img {
|
||||
width: 36px;
|
||||
@@ -132,7 +132,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
//<![CDATA[
|
||||
var imgs = document.getElementsByTagName('img');
|
||||
@@ -156,7 +156,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function check_connect(type, url) {
|
||||
var s = document.getElementById('_' + type + '_status');
|
||||
if (s) {
|
||||
|
||||
@@ -99,7 +99,7 @@ local current_node = map:get(section)
|
||||
};
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
function genQrcode(btn, urlname, sid) {
|
||||
var qrcode_div = document.getElementById("qrcode_div");
|
||||
qrcode_div.style.display = null;
|
||||
@@ -203,7 +203,7 @@ local current_node = map:get(section)
|
||||
url = b64encsafe(v_method.value + ":" + v_password.value) + "@" +
|
||||
_address + ":" +
|
||||
v_port.value + "/?";
|
||||
|
||||
|
||||
var shadow_tls;
|
||||
// Generate SS Shadow-TLS plugin parameters
|
||||
const generateShadowTLSBase64 = function(paramStr) {
|
||||
@@ -596,7 +596,7 @@ local current_node = map:get(section)
|
||||
params += opt.query("pinSHA256", dom_prefix + "tls_pinSHA256");
|
||||
params += opt.query("pcs", dom_prefix + "tls_pinSHA256");
|
||||
params += opt.query("vcn", dom_prefix + "tls_CertByName");
|
||||
|
||||
|
||||
var v_password = opt.get(dom_prefix + "hysteria2_auth_password");
|
||||
var dom_obfs_type = opt.get(dom_prefix + "hysteria2_obfs_type");
|
||||
if (dom_obfs_type && dom_obfs_type.value != "") {
|
||||
@@ -767,7 +767,7 @@ local current_node = map:get(section)
|
||||
if (!server) return '';
|
||||
return server.replace(/^\[/, '').replace(/\]$/, '');
|
||||
}
|
||||
|
||||
|
||||
function tofromUrl(btn) {
|
||||
let link = prompt('<%:Paste Share URL Here%>', '');
|
||||
if (link === null || link === "") {
|
||||
@@ -1133,7 +1133,7 @@ local current_node = map:get(section)
|
||||
var kv = ws_path_params_array[i].split('=');
|
||||
ws_path_params[decodeURIComponent(kv[0]).toLowerCase()] = decodeURIComponent(kv[1] || '');
|
||||
}
|
||||
|
||||
|
||||
if (ws_path_params.ed) {
|
||||
opt.set(dom_prefix + 'ws_path', ws_path);
|
||||
opt.set(dom_prefix + 'ws_enableEarlyData', true);
|
||||
@@ -1171,7 +1171,7 @@ local current_node = map:get(section)
|
||||
opt.set(dom_prefix + 'uot', queryParam.udp);
|
||||
opt.set(dom_prefix + 'use_finalmask', !!queryParam.fm);
|
||||
opt.set(dom_prefix + 'finalmask', queryParam.fm || "");
|
||||
|
||||
|
||||
if (queryParam["shadow-tls"]) {
|
||||
// Parsing SS Shadow-TLS plugin parameters
|
||||
const parseShadowTLSParams = function(base64Str, outObj) {
|
||||
@@ -1281,7 +1281,7 @@ local current_node = map:get(section)
|
||||
var kv = ws_path_params_array[i].split('=');
|
||||
ws_path_params[decodeURIComponent(kv[0]).toLowerCase()] = decodeURIComponent(kv[1] || '');
|
||||
}
|
||||
|
||||
|
||||
if (ws_path_params.ed) {
|
||||
opt.set(dom_prefix + 'ws_path', ws_path);
|
||||
opt.set(dom_prefix + 'ws_enableEarlyData', true);
|
||||
@@ -1468,7 +1468,7 @@ local current_node = map:get(section)
|
||||
var kv = ws_path_params_array[i].split('=');
|
||||
ws_path_params[decodeURIComponent(kv[0]).toLowerCase()] = decodeURIComponent(kv[1] || '');
|
||||
}
|
||||
|
||||
|
||||
if (ws_path_params.ed) {
|
||||
opt.set(dom_prefix + 'ws_path', ws_path);
|
||||
opt.set(dom_prefix + 'ws_enableEarlyData', true);
|
||||
@@ -1504,7 +1504,7 @@ local current_node = map:get(section)
|
||||
} else {
|
||||
dom_prefix = "xray_";
|
||||
}
|
||||
|
||||
|
||||
var m = parseNodeUrl(link);
|
||||
var password = m.passwd;
|
||||
if (password === "") {
|
||||
@@ -1611,7 +1611,7 @@ local current_node = map:get(section)
|
||||
var kv = ws_path_params_array[i].split('=');
|
||||
ws_path_params[decodeURIComponent(kv[0]).toLowerCase()] = decodeURIComponent(kv[1] || '');
|
||||
}
|
||||
|
||||
|
||||
if (ws_path_params.ed) {
|
||||
opt.set(dom_prefix + 'ws_path', ws_path);
|
||||
opt.set(dom_prefix + 'ws_enableEarlyData', true);
|
||||
@@ -1693,10 +1693,10 @@ local current_node = map:get(section)
|
||||
opt.set(dom_prefix + 'use_finalmask', !!queryParam.fm);
|
||||
opt.set(dom_prefix + 'finalmask', queryParam.fm || "");
|
||||
}
|
||||
|
||||
|
||||
opt.set(dom_prefix + 'address', unbracketIP(m.hostname));
|
||||
opt.set(dom_prefix + 'port', m.port || "443");
|
||||
|
||||
|
||||
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || "");
|
||||
opt.set(
|
||||
dom_prefix + 'tls_allowInsecure',
|
||||
@@ -1911,7 +1911,7 @@ local current_node = map:get(section)
|
||||
sessionStorage.removeItem("fromUrl");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function exportConfigFile(btn, sid) {
|
||||
window.open('<%=api.url("gen_client_config")%>?id=' + sid, "_blank")
|
||||
}
|
||||
|
||||
@@ -478,7 +478,7 @@ table td, .table .td {
|
||||
var code = ajax.encode(data);
|
||||
xhr.open("POST", url, true);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
|
||||
|
||||
if (timeout && timeout > 1000) {
|
||||
xhr.timeout = timeout;
|
||||
}
|
||||
@@ -645,7 +645,7 @@ table td, .table .td {
|
||||
updateElement(selectAllChk);
|
||||
updateElement(selectAllBtn);
|
||||
}
|
||||
|
||||
|
||||
function delete_select_nodes() {
|
||||
var ids = [];
|
||||
var visibleContainer = document.querySelector('#cbi-<%=appname%>-nodes > .cbi-tabcontainer[style*="display:block"], #cbi-<%=appname%>-nodes > .cbi-tabcontainer[style*="display: block"]');
|
||||
@@ -698,7 +698,7 @@ table td, .table .td {
|
||||
address = !reg.test(address) ? address : "";
|
||||
return { address: address, port: port };
|
||||
}
|
||||
|
||||
|
||||
function get_node_order(group) {
|
||||
let table = document.getElementById("cbi-<%=appname%>-nodes-" + group + "-table");
|
||||
if (!table) {
|
||||
@@ -756,7 +756,7 @@ table td, .table .td {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function urltest_node(cbi_id, dom) {
|
||||
if (dom.dataset.busy == "1" || !cbi_id) return;
|
||||
dom.dataset.busy = "1";
|
||||
@@ -1165,7 +1165,7 @@ table td, .table .td {
|
||||
const dom = document.getElementById('modal-mask');
|
||||
dom.style.display = 'block';
|
||||
dom.innerHTML = '<div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff;"><%:Processing, please wait…%></div>';
|
||||
|
||||
|
||||
const chunkSize = 1000; // Fragmented sending to overcome uhttpd's limitations, with each fragment containing 1000 characters.
|
||||
const totalChunks = Math.ceil(link.length / chunkSize);
|
||||
let currentChunk = 0;
|
||||
@@ -1266,7 +1266,7 @@ table td, .table .td {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const set_node_div = {
|
||||
section: '',
|
||||
open(cbi_id) {
|
||||
@@ -1606,7 +1606,7 @@ table td, .table .td {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function dom_event() {
|
||||
waitForElement('input[type="checkbox"][name*="<%=appname%>"][name*="show_node_info"]', function(el) {
|
||||
el.addEventListener("change", () => {
|
||||
@@ -1662,7 +1662,7 @@ table td, .table .td {
|
||||
};
|
||||
<% end -%>
|
||||
dom_event();
|
||||
|
||||
|
||||
const links = document.querySelectorAll('a');
|
||||
links.forEach(link => {
|
||||
link.addEventListener('click', (e) => {
|
||||
|
||||
@@ -87,9 +87,9 @@ local has_old_geosite = fs.access("/tmp/bak_v2ray/geosite.dat")
|
||||
var checkBoxList = [];
|
||||
var len = domList.length;
|
||||
while(len--) {
|
||||
var dom = domList[len];
|
||||
if(dom.type == 'checkbox' && dom.checked) {
|
||||
checkBoxList.push(dom.name);
|
||||
var dom = domList[len];
|
||||
if(dom.type == 'checkbox' && dom.checked) {
|
||||
checkBoxList.push(dom.name);
|
||||
}
|
||||
}
|
||||
XHR.get('<%=api.url("update_rules")%>', {
|
||||
@@ -106,7 +106,7 @@ local has_old_geosite = fs.access("/tmp/bak_v2ray/geosite.dat")
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function rollback_rules(btn, type) {
|
||||
let ori_val = btn.value;
|
||||
btn.disabled = true;
|
||||
|
||||
@@ -389,7 +389,7 @@ table td, .table .td {
|
||||
'' + table_html +
|
||||
'</div>'
|
||||
}
|
||||
|
||||
|
||||
function addTabDOM(li, content) {
|
||||
let tab_ul_html = '<ul class="cbi-tabmenu">';
|
||||
let tab_content_html = '<fieldset class="cbi-section-shunt_rule cbi-section-shunt_rule-tabbed" id="cbi-<%=appname%>-shunt_rules">';
|
||||
@@ -413,7 +413,7 @@ table td, .table .td {
|
||||
if (default_group) {
|
||||
cbi_t_switch("<%=appname%>.shunt_rules", default_group)
|
||||
}
|
||||
|
||||
|
||||
origin_group_shunt_rule_order = {};
|
||||
for (let group in group_shunt_rules) {
|
||||
origin_group_shunt_rule_order[group] = get_shunt_rule_order(group);
|
||||
|
||||
@@ -17,7 +17,7 @@ local prefix = self.option_prefix or ""
|
||||
if (x && x.status == 200 && data.code == 1) {
|
||||
const private_key_dom = getOption("<%=self.config%>", "<%=section%>", "<%=prefix%>wireguard_private_key");
|
||||
private_key_dom.value = data.data.private_key;
|
||||
|
||||
|
||||
const public_key_dom = getOption("<%=self.config%>", "<%=section%>", "<%=prefix%>wireguard_public_key");
|
||||
public_key_dom.value = data.data.public_key;
|
||||
} else {
|
||||
|
||||
@@ -21,7 +21,7 @@ local sectiontype = self.sectiontype
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
var edit_btn = document.getElementById("cbi-<%=config%>-<%=sectiontype%>").getElementsByClassName("cbi-button cbi-button-edit");
|
||||
for (var i = 0; i < edit_btn.length; i++) {
|
||||
try {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
if [ -e "/etc/config/ucitrack" ]; then
|
||||
uci -q batch <<-EOF
|
||||
delete ucitrack.@passwall2[-1]
|
||||
delete ucitrack.@passwall2[-1]
|
||||
add ucitrack passwall2
|
||||
set ucitrack.@passwall2[-1].init=passwall2
|
||||
commit ucitrack
|
||||
|
||||
@@ -16,7 +16,7 @@ config global
|
||||
dns.google.com 8.8.8.8'
|
||||
option log_node '1'
|
||||
option loglevel 'error'
|
||||
|
||||
|
||||
config global_haproxy
|
||||
option balancing_enable '0'
|
||||
|
||||
@@ -53,7 +53,7 @@ config global_app
|
||||
|
||||
config global_subscribe
|
||||
option filter_keyword_mode '1'
|
||||
|
||||
|
||||
config global_singbox
|
||||
|
||||
config nodes 'examplenode'
|
||||
|
||||
@@ -781,7 +781,7 @@ run_ipset_chinadns_ng() {
|
||||
node_servers=$(uci show "${CONFIG}" | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2)
|
||||
hosts_foreach "node_servers" host_from_url | grep '[a-zA-Z]$' | sort -u | grep -v "engage.cloudflareclient.com" > $TMP_ACL_PATH/vpslist
|
||||
}
|
||||
|
||||
|
||||
[ -n "${ipset}" ] && {
|
||||
set_names=$ipset
|
||||
vps_set_names="psw2_vps,psw2_vps6"
|
||||
|
||||
@@ -213,7 +213,7 @@ function acl_app(l)
|
||||
add_args(run_args, "config_file", config_file)
|
||||
add_args(run_args, "loglevel", v.loglevel)
|
||||
add_args(run_args, "log_file", log_file)
|
||||
|
||||
|
||||
local out = io.open(api.TMP_ACL_PATH .. "/acl_node_" .. flag , "a")
|
||||
out:write(table.concat(run_args, " "))
|
||||
out:close()
|
||||
|
||||
@@ -120,9 +120,9 @@ function copy_instance(var)
|
||||
local TMP_DNSMASQ_PATH = var["TMP_DNSMASQ_PATH"]
|
||||
local conf_lines = {}
|
||||
local DEFAULT_DNSMASQ_CFGID = sys.exec("echo -n $(uci -q show dhcp.@dnsmasq[0] | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')")
|
||||
|
||||
|
||||
local conf_file = "/var/etc/dnsmasq.conf." .. DEFAULT_DNSMASQ_CFGID
|
||||
|
||||
|
||||
local retry = 5
|
||||
while not fs.access(conf_file) and retry > 0 do
|
||||
api.nixio.nanosleep(1, 0)
|
||||
|
||||
@@ -291,7 +291,7 @@ load_acl() {
|
||||
}
|
||||
|
||||
local comment_l="$(i18n "Local")"
|
||||
|
||||
|
||||
if [ -n "$node" ] && ([ -z "$no_tcp_local_proxy" ] || [ -z "$no_udp_local_proxy" ]); then
|
||||
[ -n "$dns_redirect_port" ] && {
|
||||
#$ipt_m -A PSW2_OUTPUT $(comment "${comment_l}") -p udp --dport 53 -j ACCEPT
|
||||
@@ -390,7 +390,7 @@ load_acl() {
|
||||
|
||||
$ipt_m -I OUTPUT $(comment "mangle-OUTPUT-PSW2") -o lo -j RETURN
|
||||
insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -m mark --mark ${FWMARK} -j RETURN"
|
||||
|
||||
|
||||
$ip6t_m -I OUTPUT $(comment "mangle-OUTPUT-PSW2") -o lo -j RETURN
|
||||
insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -m mark --mark ${FWMARK} -j RETURN"
|
||||
|
||||
@@ -463,7 +463,7 @@ load_acl() {
|
||||
log 2 "${msg}$(i18n "not proxy all %s" "TCP")"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
[ -n "$udp_no_redir_ports" ] && {
|
||||
if ! has_1_65535 "$udp_no_redir_ports"; then
|
||||
[ "$_ipv4" != "1" ] && add_port_rules "$ip6t_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp" $udp_no_redir_ports "-j RETURN" 2>/dev/null
|
||||
@@ -475,7 +475,7 @@ load_acl() {
|
||||
log 2 "${msg}$(i18n "not proxy all %s" "UDP")"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if ([ -z "$no_tcp_proxy" ] || [ -z "$no_udp_proxy" ]) && [ -n "$dns_redirect_port" ]; then
|
||||
$ipt_m -A PSW2 $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j ACCEPT
|
||||
$ipt_m -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j ACCEPT
|
||||
@@ -508,7 +508,7 @@ load_acl() {
|
||||
add_shunt_t_rule "${shunt_list4}" "$ipt_n -A PSW2 $(comment "$remarks") -p icmp ${_ipt_source}" "$(REDIRECT)"
|
||||
$ipt_n -A PSW2 $(comment "$remarks") -p icmp ${_ipt_source} $(REDIRECT)
|
||||
}
|
||||
|
||||
|
||||
[ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && {
|
||||
$ip6t_n -A PSW2 $(comment "$remarks") -p ipv6-icmp ${_ipt_source} -d $FAKE_IP_6 $(REDIRECT) 2>/dev/null
|
||||
add_shunt_t_rule "${shunt_list6}" "$ip6t_n -A PSW2 $(comment "$remarks") -p ipv6-icmp ${_ipt_source}" "$(REDIRECT)" 2>/dev/null
|
||||
@@ -650,12 +650,12 @@ update_wan_sets() {
|
||||
|
||||
add_firewall_rule() {
|
||||
log_i18n 0 "Starting to load %s firewall rules..." "iptables"
|
||||
|
||||
|
||||
ipset -! create $IPSET_LOCAL nethash maxelem 1048576
|
||||
ipset -! create $IPSET_DIRECT nethash maxelem 1048576
|
||||
ipset -! create $IPSET_VPS iphash maxelem 1048576
|
||||
ipset -! create $IPSET_WAN nethash maxelem 1048576
|
||||
|
||||
|
||||
ipset -! create $IPSET_LOCAL6 nethash family inet6 maxelem 1048576
|
||||
ipset -! create $IPSET_DIRECT6 nethash family inet6 maxelem 1048576
|
||||
ipset -! create $IPSET_VPS6 iphash family inet6 maxelem 1048576
|
||||
@@ -734,7 +734,7 @@ add_firewall_rule() {
|
||||
$ipt_n -N PSW2
|
||||
$ipt_n -A PSW2 $(dst $IPSET_VPS) -j RETURN
|
||||
$ipt_n -A PSW2 $(comment "WAN_IP_RETURN") $(dst $IPSET_WAN) -j RETURN
|
||||
|
||||
|
||||
[ "$accept_icmp" = "1" ] && insert_rule_after "$ipt_n" "PREROUTING" "prerouting_rule" "$(dst $IPSET_DIRECT !) -p icmp -j PSW2"
|
||||
[ -z "${is_tproxy}" ] && insert_rule_after "$ipt_n" "PREROUTING" "prerouting_rule" "$(dst $IPSET_DIRECT !) -p tcp -j PSW2"
|
||||
|
||||
@@ -784,7 +784,7 @@ add_firewall_rule() {
|
||||
$ip6t_n -A PSW2_OUTPUT $(dst $IPSET_VPS6) -j RETURN
|
||||
$ip6t_n -A PSW2_OUTPUT -m mark --mark 0xff/0xff -j RETURN
|
||||
}
|
||||
|
||||
|
||||
$ip6t_n -N PSW2_DNS
|
||||
if [ $(config_n_get @global[0] dns_redirect "1") = "0" ]; then
|
||||
#Only hijack when dest address is local IP
|
||||
@@ -945,7 +945,7 @@ gen_include() {
|
||||
${__ipt}
|
||||
|
||||
${__ip6t}
|
||||
|
||||
|
||||
return 0
|
||||
EOF
|
||||
return 0
|
||||
|
||||
@@ -26,7 +26,7 @@ while [ "$ENABLED" -eq 1 ]; do
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
rm -f $LOCK_FILE
|
||||
sleep 58s
|
||||
done
|
||||
@@ -157,20 +157,20 @@ insert_nftset() {
|
||||
RS = "[ \t\n\r]+"
|
||||
ORS = ""
|
||||
}
|
||||
$0 != "" {
|
||||
if (!first) {
|
||||
printf "add element %s %s { \n", t, n
|
||||
$0 != "" {
|
||||
if (!first) {
|
||||
printf "add element %s %s { \n", t, n
|
||||
first = 1
|
||||
} else {
|
||||
print ",\n"
|
||||
}
|
||||
printf " %s", $0
|
||||
}
|
||||
END {
|
||||
if (first) {
|
||||
print "\n }\n"
|
||||
}
|
||||
}' | nft -f -
|
||||
} else {
|
||||
print ",\n"
|
||||
}
|
||||
printf " %s", $0
|
||||
}
|
||||
END {
|
||||
if (first) {
|
||||
print "\n }\n"
|
||||
}
|
||||
}' | nft -f -
|
||||
}
|
||||
|
||||
gen_nftset() {
|
||||
@@ -455,7 +455,7 @@ load_acl() {
|
||||
continue
|
||||
fi
|
||||
msg="${msg1}${msg}"
|
||||
|
||||
|
||||
[ -n "$tcp_no_redir_ports" ] && {
|
||||
if ! has_1_65535 "$tcp_no_redir_ports"; then
|
||||
nft "add rule $NFTABLE_NAME $nft_prerouting_chain ${_ipt_source} ip protocol tcp $(factor $tcp_no_redir_ports "tcp dport") counter return comment \"$remarks\""
|
||||
@@ -467,7 +467,7 @@ load_acl() {
|
||||
log 2 "${msg}$(i18n "not proxy all %s" "TCP")"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
[ -n "$udp_no_redir_ports" ] && {
|
||||
if ! has_1_65535 "$udp_no_redir_ports"; then
|
||||
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_no_redir_ports "udp dport") counter return comment \"$remarks\""
|
||||
@@ -958,7 +958,7 @@ gen_include() {
|
||||
|
||||
cat <<-EOF >> $FWI
|
||||
${__nft}
|
||||
|
||||
|
||||
return 0
|
||||
EOF
|
||||
return 0
|
||||
|
||||
@@ -155,7 +155,7 @@ do
|
||||
if true then
|
||||
local szType = "@global[0]"
|
||||
local option = "node"
|
||||
|
||||
|
||||
local node_id = uci_get(szType, option)
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = true,
|
||||
@@ -651,7 +651,7 @@ local function parseClashNode(node, add_mode, group, sub_cfg)
|
||||
end
|
||||
end
|
||||
result.transport = node.network and string.lower(node.network) or "tcp"
|
||||
if result.type == "sing-box" and result.transport == "raw" then
|
||||
if result.type == "sing-box" and result.transport == "raw" then
|
||||
result.transport = "tcp"
|
||||
elseif result.type == "Xray" and result.transport == "tcp" then
|
||||
result.transport = "raw"
|
||||
@@ -723,7 +723,7 @@ local function parseClashNode(node, add_mode, group, sub_cfg)
|
||||
result.reality_shortId = (node["reality-opts"] and node["reality-opts"]["short-id"]) or nil
|
||||
end
|
||||
result.transport = node.network and string.lower(node.network) or "tcp"
|
||||
if result.type == "sing-box" and result.transport == "raw" then
|
||||
if result.type == "sing-box" and result.transport == "raw" then
|
||||
result.transport = "tcp"
|
||||
elseif result.type == "Xray" and result.transport == "tcp" then
|
||||
result.transport = "raw"
|
||||
@@ -914,7 +914,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
result.protocol = hostInfo[#hostInfo-3]
|
||||
result.method = hostInfo[#hostInfo-2]
|
||||
result.obfs = hostInfo[#hostInfo-1]
|
||||
result.password = base64Decode(hostInfo[#hostInfo])
|
||||
result.password = base64Decode(hostInfo[#hostInfo])
|
||||
local params = {}
|
||||
for _, v in pairs(split(dat[2], '&')) do
|
||||
local s = v:find("=", 1, true)
|
||||
@@ -1001,7 +1001,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
|
||||
if not info.net then info.net = "tcp" end
|
||||
info.net = string.lower(info.net)
|
||||
if result.type == "sing-box" and info.net == "raw" then
|
||||
if result.type == "sing-box" and info.net == "raw" then
|
||||
info.net = "tcp"
|
||||
elseif result.type == "Xray" and info.net == "tcp" then
|
||||
info.net = "raw"
|
||||
@@ -1282,7 +1282,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
|
||||
if params.type then
|
||||
params.type = string.lower(params.type)
|
||||
if result.type == "sing-box" and params.type == "raw" then
|
||||
if result.type == "sing-box" and params.type == "raw" then
|
||||
params.type = "tcp"
|
||||
elseif result.type == "Xray" and params.type == "tcp" then
|
||||
params.type = "raw"
|
||||
@@ -1447,7 +1447,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
log(2, i18n.translatef("Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings.", "Trojan", "Trojan"))
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
local alias = ""
|
||||
if content:find("#") then
|
||||
local idx_sp = content:find("#")
|
||||
@@ -1511,7 +1511,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
|
||||
if not params.type then params.type = "tcp" end
|
||||
params.type = string.lower(params.type)
|
||||
if result.type == "sing-box" and params.type == "raw" then
|
||||
if result.type == "sing-box" and params.type == "raw" then
|
||||
params.type = "tcp"
|
||||
elseif result.type == "Xray" and params.type == "tcp" then
|
||||
params.type = "raw"
|
||||
@@ -1652,7 +1652,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
if ({ xhttp=true, kcp=true, mkcp=true })[params.type] and result.type ~= "Xray" and has_xray then
|
||||
result.type = "Xray"
|
||||
end
|
||||
if result.type == "sing-box" and params.type == "raw" then
|
||||
if result.type == "sing-box" and params.type == "raw" then
|
||||
params.type = "tcp"
|
||||
elseif result.type == "Xray" and params.type == "tcp" then
|
||||
params.type = "raw"
|
||||
@@ -1791,7 +1791,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
content = content:sub(0, idx_sp - 1)
|
||||
end
|
||||
result.remarks = UrlDecode(alias)
|
||||
|
||||
|
||||
local query = split(content:gsub("/%?", "?"), '%?')
|
||||
local host_port = query[1]
|
||||
local params = {}
|
||||
@@ -2508,7 +2508,7 @@ local function update_node(manual)
|
||||
uci_set(cfgid, "chain_proxy", "3")
|
||||
uci_set(cfgid, "outbound_iface", outbound_iface_group)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||