update 2023-08-22 23:36:10

This commit is contained in:
github-actions[bot] 2023-08-22 23:36:10 +08:00
parent 31d6037752
commit f702f28149
100 changed files with 3293 additions and 1181 deletions

View File

@ -20,7 +20,7 @@ base_setting_section = m:section(TypedSection, "base_setting", translate("base s
base_setting_section.anonymous = false
base_setting_section.addremove = false
dial_num = base_setting_section:option(Value, "dial_num", translate("数量"))
dial_num = base_setting_section:option(Value, "dial_num", translate("数量"))
dial_num.default = 2
dial_num.datatype = "range(1,249)"

View File

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-openclash
PKG_VERSION:=0.45.129
PKG_VERSION:=0.45.141
PKG_RELEASE:=beta
PKG_MAINTAINER:=vernesong <https://github.com/vernesong/OpenClash>

View File

@ -383,7 +383,7 @@ function action_remove_all_core()
end
function action_one_key_update()
return luci.sys.call("bash /usr/share/openclash/openclash_update.sh 'one_key_update' >/dev/null 2>&1 &")
return luci.sys.call("rm -rf /tmp/*_last_version 2>/dev/null && bash /usr/share/openclash/openclash_update.sh 'one_key_update' >/dev/null 2>&1 &")
end
local function dler_login_info_save()
@ -1386,6 +1386,7 @@ function action_backup()
luci.http.prepare_content("application/x-targz")
luci.ltn12.pump.all(reader, luci.http.write)
luci.sys.call("rm -rf /etc/openclash/openclash >/dev/null 2>&1")
end
function action_backup_ex_core()
@ -1399,10 +1400,10 @@ function action_backup_ex_core()
luci.http.prepare_content("application/x-targz")
luci.ltn12.pump.all(reader, luci.http.write)
luci.sys.call("rm -rf /etc/openclash/openclash >/dev/null 2>&1")
end
function action_backup_only_config()
local config = luci.sys.call("cp /etc/config/openclash /etc/openclash/openclash >/dev/null 2>&1")
local reader = ltn12_popen("tar -C '/etc/openclash' -cz './config' 2>/dev/null")
luci.http.header(
@ -1415,7 +1416,6 @@ function action_backup_only_config()
end
function action_backup_only_core()
local config = luci.sys.call("cp /etc/config/openclash /etc/openclash/openclash >/dev/null 2>&1")
local reader = ltn12_popen("tar -C '/etc/openclash' -cz './core' 2>/dev/null")
luci.http.header(
@ -1428,7 +1428,6 @@ function action_backup_only_core()
end
function action_backup_only_rule()
local config = luci.sys.call("cp /etc/config/openclash /etc/openclash/openclash >/dev/null 2>&1")
local reader = ltn12_popen("tar -C '/etc/openclash' -cz './rule_provider' 2>/dev/null")
luci.http.header(
@ -1441,7 +1440,6 @@ function action_backup_only_rule()
end
function action_backup_only_proxy()
local config = luci.sys.call("cp /etc/config/openclash /etc/openclash/openclash >/dev/null 2>&1")
local reader = ltn12_popen("tar -C '/etc/openclash' -cz './proxy_provider' 2>/dev/null")
luci.http.header(

View File

@ -265,6 +265,10 @@ o = s:taboption("meta", Flag, "enable_tcp_concurrent", font_red..bold_on..transl
o.description = font_red..bold_on..translate("TCP Concurrent Request IPs, Choose The Lowest Latency One To Connection")..bold_off..font_off
o.default = "0"
o = s:taboption("meta", Flag, "enable_unified_delay", font_red..bold_on..translate("Enable Unified Delay")..bold_off..font_off)
o.description = font_red..bold_on..translate("Change the delay calculation method to remove extra delays such as handshaking")..bold_off..font_off
o.default = "0"
o = s:taboption("meta", ListValue, "find_process_mode", translate("Enable Process Rule"))
o.description = translate("Whether to Enable Process Rules, If You Are Not Sure, Please Choose off Which Useful in Router Environment")
o:value("0", translate("Disable"))
@ -294,11 +298,9 @@ o:value("memconservative", translate("Memconservative"))
o:value("standard", translate("Standard"))
o.default = "0"
o = s:taboption("meta", ListValue, "enable_geoip_dat", translate("Enable GeoIP Dat"))
o = s:taboption("meta", Flag, "enable_geoip_dat", translate("Enable GeoIP Dat"))
o.description = translate("Replace GEOIP MMDB With GEOIP Dat, Large Size File")..", "..font_red..bold_on..translate("Need Download First")..bold_off..font_off
o.default = 0
o:value("0", translate("Disable"))
o:value("1", translate("Enable"))
o = s:taboption("meta", Flag, "enable_meta_sniffer", font_red..bold_on..translate("Enable Sniffer")..bold_off..font_off)
o.description = font_red..bold_on..translate("Sniffer Will Prevent Domain Name Proxy and DNS Hijack Failure")..bold_off..font_off
@ -390,7 +392,7 @@ o.default = 0
custom_rules = s:taboption("rules", Value, "custom_rules")
custom_rules:depends("enable_custom_clash_rules", 1)
custom_rules.template = "cbi/tvalue"
custom_rules.description = translate("Custom Priority Rules Here, For More Go:").." ".."<a href='javascript:void(0)' onclick='javascript:return winOpen(\"https://lancellc.gitbook.io/clash/clash-config-file/rules\")'>https://lancellc.gitbook.io/clash/clash-config-file/rules</a>".." ,"..translate("IP To CIDR:").." ".."<a href='javascript:void(0)' onclick='javascript:return winOpen(\"http://ip2cidr.com\")'>http://ip2cidr.com</a>"
custom_rules.description = font_green..bold_on..translate("(Priority)")..bold_off..font_off.." "..translate("Custom Rules Here, For More Go:").." ".."<a href='javascript:void(0)' onclick='javascript:return winOpen(\"https://lancellc.gitbook.io/clash/clash-config-file/rules\")'>https://lancellc.gitbook.io/clash/clash-config-file/rules</a>".." ,"..translate("IP To CIDR:").." ".."<a href='javascript:void(0)' onclick='javascript:return winOpen(\"http://ip2cidr.com\")'>http://ip2cidr.com</a>"
custom_rules.rows = 20
custom_rules.wrap = "off"
@ -410,7 +412,7 @@ end
custom_rules_2 = s:taboption("rules", Value, "custom_rules_2")
custom_rules_2:depends("enable_custom_clash_rules", 1)
custom_rules_2.template = "cbi/tvalue"
custom_rules_2.description = translate("Custom Extended Rules Here, For More Go:").." ".."<a href='javascript:void(0)' onclick='javascript:return winOpen(\"https://lancellc.gitbook.io/clash/clash-config-file/rules\")'>https://lancellc.gitbook.io/clash/clash-config-file/rules</a>".." ,"..translate("IP To CIDR:").." ".."<a href='javascript:void(0)' onclick='javascript:return winOpen(\"http://ip2cidr.com\")'>http://ip2cidr.com</a>"
custom_rules_2.description = font_green..bold_on..translate("(Extended)")..bold_off..font_off.." "..translate("Custom Rules Here, For More Go:").." ".."<a href='javascript:void(0)' onclick='javascript:return winOpen(\"https://lancellc.gitbook.io/clash/clash-config-file/rules\")'>https://lancellc.gitbook.io/clash/clash-config-file/rules</a>".." ,"..translate("IP To CIDR:").." ".."<a href='javascript:void(0)' onclick='javascript:return winOpen(\"http://ip2cidr.com\")'>http://ip2cidr.com</a>"
custom_rules_2.rows = 20
custom_rules_2.wrap = "off"

View File

@ -233,7 +233,7 @@ end
o:value("DIRECT")
o:value("REJECT")
o = s:option(ListValue, "ChatGPT", translate("ChatGPT"))
o = s:option(ListValue, "OpenAI", translate("OpenAI"))
o:depends("rule_name", "lhie1")
o.rmempty = true
for groupname in string.gmatch(groupnames, "([^'##\n']+)##") do
@ -387,6 +387,17 @@ end
o:value("DIRECT")
o:value("REJECT")
o = s:option(ListValue, "AntiIP", translate("Anti IP"))
o:depends("rule_name", "lhie1")
o.rmempty = true
for groupname in string.gmatch(groupnames, "([^'##\n']+)##") do
if groupname ~= nil and groupname ~= "" then
o:value(groupname)
end
end
o:value("DIRECT")
o:value("REJECT")
o = s:option(ListValue, "Domestic", translate("Domestic"))
o:depends("rule_name", "lhie1")
o:depends("rule_name", "ConnersHua")

View File

@ -791,39 +791,39 @@ o.template = "openclash/other_stream_option"
o.value = "Google"
o:depends("stream_auto_select_google_not_cn", "1")
--ChatGPT
o = s:taboption("stream_enhance", Flag, "stream_auto_select_chatgpt", font_red..translate("ChatGPT")..font_off)
--OpenAI
o = s:taboption("stream_enhance", Flag, "stream_auto_select_openai", font_red..translate("OpenAI")..font_off)
o.default = 0
o:depends("stream_auto_select", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_chatgpt", translate("Group Filter"))
o.default = "ChatGPT"
o.placeholder = "ChatGPT"
o = s:taboption("stream_enhance", Value, "stream_auto_select_group_key_openai", translate("Group Filter"))
o.default = "OpenAI|ChatGPT"
o.placeholder = "OpenAI|ChatGPT"
o.description = translate("It Will Be Searched According To The Regex When Auto Search Group Fails")
o:depends("stream_auto_select_chatgpt", "1")
o:depends("stream_auto_select_openai", "1")
o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_chatgpt", translate("Unlock Region Filter"))
o = s:taboption("stream_enhance", Value, "stream_auto_select_region_key_openai", translate("Unlock Region Filter"))
o.default = ""
o.placeholder = "US"
o.description = translate("It Will Be Selected Region(Country Shortcode) According To The Regex")
o:depends("stream_auto_select_chatgpt", "1")
o:depends("stream_auto_select_openai", "1")
function o.validate(self, value)
if value ~= m.uci:get("openclash", "config", "stream_auto_select_region_key_chatgpt") then
fs.unlink("/tmp/openclash_ChatGPT_region")
if value ~= m.uci:get("openclash", "config", "stream_auto_select_region_key_openai") then
fs.unlink("/tmp/openclash_OpenAI_region")
end
return value
end
o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_chatgpt", translate("Unlock Nodes Filter"))
o = s:taboption("stream_enhance", Value, "stream_auto_select_node_key_openai", translate("Unlock Nodes Filter"))
o.default = ""
o.description = translate("It Will Be Selected Nodes According To The Regex")
o:depends("stream_auto_select_chatgpt", "1")
o:depends("stream_auto_select_openai", "1")
o = s:taboption("stream_enhance", DummyValue, "ChatGPT", translate("Manual Test"))
o = s:taboption("stream_enhance", DummyValue, "OpenAI", translate("Manual Test"))
o.rawhtml = true
o.template = "openclash/other_stream_option"
o.value = "ChatGPT"
o:depends("stream_auto_select_chatgpt", "1")
o.value = "OpenAI"
o:depends("stream_auto_select_openai", "1")
---- update Settings
o = s:taboption("rules_update", Flag, "other_rule_auto_update", translate("Auto Update"))

View File

@ -230,6 +230,9 @@ function line_tolocal(str){
if (res) {
var dt = new Date(res[1]);
}
else {
var dtt = new Date(v.substring(0,19));
}
if (dt && dt != "Invalid Date"){
if (v.indexOf("level=") != -1) {
var log_info = v.substring(res[1].length + 7);
@ -240,10 +243,14 @@ function line_tolocal(str){
cstrt[cn]=dt.getFullYear()+"-"+p(dt.getMonth()+1)+"-"+p(dt.getDate())+" "+p(dt.getHours())+":"+p(dt.getMinutes())+":"+p(dt.getSeconds())+log_info;
cn = cn + 1;
}
else{
else if (dtt && dtt != "Invalid Date" && v.substring(28,33).indexOf(" ERR ") == -1) {
strt[sn]=v;
sn = sn + 1;
}
else{
cstrt[cn]=v;
cn = cn + 1;
}
})
return [strt,cstrt]
};

View File

@ -352,7 +352,21 @@
};
}
else if ( status.startlog != "\n" && status.startlog != "" ) {
startlog.innerHTML = '<b style=color:green>'+status.startlog+'</b>';
if ( status.startlog.match("Tip:") || status.startlog.match("提示:")) {
startlog.innerHTML = '<b style=color:#ff6f00>'+status.startlog+'</b>';
}
else if ( status.startlog.match("Error:") || status.startlog.match("错误:")) {
startlog.innerHTML = '<b style=color:#FF0000>'+status.startlog+'</b>';
}
else if ( status.startlog.match("Warning:") || status.startlog.match("警告:")) {
startlog.innerHTML = '<b style=color:#ff00bb>'+status.startlog+'</b>';
}
else if ( status.startlog.match("Watchdog:") || status.startlog.match("守护程序:")) {
startlog.innerHTML = '<b style=color:#b300ff>'+status.startlog+'</b>';
}
else {
startlog.innerHTML = '<b style=color:green>'+status.startlog+'</b>';
};
};
};
});

View File

@ -103,7 +103,6 @@ local sectiontype = "_"..self.config.."_"..string.match(self.sectiontype, "[%w_]
#tab-header-<%=self.config%>-<%=self.sectiontype%> ul li.cbi-tab > a{
font-weight: bolder;
color: unset;
}
#tab-header-<%=self.config%>-<%=self.sectiontype%> ul li a:hover{

View File

@ -70,7 +70,6 @@ local sectiontype = "_"..self.config.."_"..string.match(self.sectiontype, "[%w_]
#tab-header-<%=self.config%>-<%=self.sectiontype%> ul li.cbi-tab > a{
font-weight: bolder;
color: unset;
}
#tab-header-<%=self.config%>-<%=self.sectiontype%> ul li a:hover{

View File

@ -23,7 +23,7 @@
<option value="linux-mipsle-hardfloat"><%:linux-mipsle-hardfloat%></option>
<option value="0"><%:Not Set%></option>
</select></td>
<td width="25%"><%:Release Branch Selected%></td>
<td width="25%"><%:Release Branch Selected (Auto-save when you click to update or download)%></td>
<td width="25%" align="left"><select id="RELEASE_BRANCH">
<option value="master">Master</option>
<option value="dev">Developer</option>
@ -315,7 +315,21 @@
};
}
else if ( status.startlog != "\n" && status.startlog != "" ) {
update_tip.innerHTML = '<b style=color:green>'+status.startlog+'</b>';
if ( status.startlog.match("Tip:") || status.startlog.match("提示:")) {
update_tip.innerHTML = '<b style=color:#ff6f00>'+status.startlog+'</b>';
}
else if ( status.startlog.match("Error:") || status.startlog.match("错误:")) {
update_tip.innerHTML = '<b style=color:#FF0000>'+status.startlog+'</b>';
}
else if ( status.startlog.match("Warning:") || status.startlog.match("警告:")) {
update_tip.innerHTML = '<b style=color:#ff00bb>'+status.startlog+'</b>';
}
else if ( status.startlog.match("Watchdog:") || status.startlog.match("守护程序:")) {
update_tip.innerHTML = '<b style=color:#b300ff>'+status.startlog+'</b>';
}
else {
update_tip.innerHTML = '<b style=color:green>'+status.startlog+'</b>';
};
};
};
});

View File

@ -575,11 +575,14 @@ msgstr "指定流量(策略)的代理方式,只支持选择(策略组),
msgid "Custom Clash Rules"
msgstr "*自定义规则"
msgid "Custom Priority Rules Here, For More Go:"
msgstr "设置自定义规则(优先匹配),详细信息请参阅:"
msgid "Custom Rules Here, For More Go:"
msgstr "在上方设置自定义规则,详细信息请参阅:"
msgid "Custom Extended Rules Here, For More Go:"
msgstr "设置自定义规则(候补匹配),详细信息请参阅:"
msgid "(Priority)"
msgstr "(优先匹配)"
msgid "(Extended)"
msgstr "(候补匹配)"
msgid "IP To CIDR:"
msgstr "在线 IP 段转 CIDR 地址:"
@ -1332,8 +1335,8 @@ msgstr "注意客户端可能无法更新因为squashfs格式的固件更
msgid "Compiled Version Selected (Auto-save when you click to update or download)"
msgstr "已选择编译版本(点击更新或下载时自动保存)"
msgid "Release Branch Selected"
msgstr "已选择更新分支"
msgid "Release Branch Selected (Auto-save when you click to update or download)"
msgstr "已选择更新分支(点击更新或下载时自动保存)"
msgid "CPU Architecture"
msgstr "处理器架构"
@ -1611,8 +1614,8 @@ msgstr "OpenClash 更新失败,文件保存在 /tmp/openclash.ipk请尝试
msgid "Download Failed, Please Check The Network or Try Again Later!"
msgstr "下载失败,请检查网络或稍后再试!"
msgid "Failed to Get Version Information, Please Try Again Later..."
msgstr "获取版本信息失败,请稍后再试..."
msgid "Error: Failed to Get Version Information, Please Try Again Later..."
msgstr "错误:获取版本信息失败,请稍后再试..."
msgid "OpenClash Has not Been Updated, Stop Continuing!"
msgstr "OpenClash 没有更新,停止继续操作!"
@ -2628,8 +2631,8 @@ msgstr "提示开始自动选择检测Bilibili 解锁节点..."
msgid "Tip: Start Auto Select Proxy For Google Not CN Unlock..."
msgstr "提示开始自动选择检测Google 非送中节点..."
msgid "Tip: Start Auto Select Proxy For ChatGPT Unlock..."
msgstr "提示:开始自动选择(检测)ChatGPT 解锁节点..."
msgid "Tip: Start Auto Select Proxy For OpenAI Unlock..."
msgstr "提示:开始自动选择(检测)OpenAI 解锁节点..."
msgid "Netflix Group:"
msgstr "Netflix 策略组:"
@ -2670,8 +2673,8 @@ msgstr "Bilibili 策略组:"
msgid "Google Group:"
msgstr "Google 策略组:"
msgid "ChatGPT Group:"
msgstr "ChatGPT 策略组:"
msgid "OpenAI Group:"
msgstr "OpenAI 策略组:"
msgid "full support"
msgstr "完整解锁"
@ -3418,4 +3421,19 @@ msgid "Other Parameters"
msgstr "其他附加配置"
msgid "Edit Your Other Parameters Here"
msgstr "请在此编辑您的附加配置"
msgstr "请在此编辑您的附加配置"
msgid "Error: Config Not Found, Switch Config File to"
msgstr "错误:未找到配置文件,切换至配置文件"
msgid "Warning: Skip the nameserver-policy that Core not Support"
msgstr "警告:跳过核心不支持的 nameserver-policy 规则"
msgid "Enable Unified Delay"
msgstr "*启用统一延迟"
msgid "Change the delay calculation method to remove extra delays such as handshaking"
msgstr "更换延迟计算方式,通过去除握手等额外开销来降低延迟数值"
msgid "Tip: If the download fails, try setting the CDN in Overwrite Settings - General Settings - Github Address Modify Options"
msgstr "提示:如果下载失败,您可以尝试在覆写设置 - 常规设置 - Github地址修改选项中设置CDN"

View File

@ -168,13 +168,13 @@ config dns_servers
option group 'fallback'
option type 'https'
option ip 'jp.tiar.app/dns-query'
option enabled '1'
option enabled '0'
config dns_servers
option group 'fallback'
option type 'https'
option ip 'jp.tiarap.org/dns-query'
option enabled '1'
option enabled '0'
config dns_servers
option group 'fallback'
@ -186,4 +186,46 @@ config dns_servers
option group 'fallback'
option ip 'dot.tiar.app'
option type 'tls'
option enabled '0'
config dns_servers
option enabled '0'
option group 'fallback'
option type 'https'
option ip 'doh.dnslify.com/dns-query'
config dns_servers
option enabled '0'
option group 'fallback'
option ip 'dns.twnic.tw/dns-query'
option type 'https'
config dns_servers
option enabled '1'
option group 'fallback'
option ip 'dns.oszx.co/dns-query'
option type 'https'
config dns_servers
option enabled '0'
option group 'fallback'
option ip 'doh.applied-privacy.net/query'
option type 'https'
config dns_servers
option enabled '0'
option group 'fallback'
option ip 'dnsforge.de/dns-query'
option type 'https'
config dns_servers
option enabled '0'
option group 'fallback'
option ip 'doh.ffmuc.net/dns-query'
option type 'https'
config dns_servers
option enabled '0'
option group 'fallback'
option type 'https'
option ip 'doh.mullvad.net/dns-query'

View File

@ -83,7 +83,7 @@ save_dnsmasq_server() {
if [ -z "$1" ] || [ "$1" == "127.0.0.1#${dns_port}" ]; then
return
fi
uci -q add_list openclash.config.dnsmasq_server="$1"
}
@ -91,7 +91,7 @@ set_dnsmasq_server() {
if [ -z "$1" ] || [ "$1" == "127.0.0.1#${dns_port}" ]; then
return
fi
uci -q add_list dhcp.@dnsmasq[0].server="$1"
}
@ -111,7 +111,7 @@ change_dns() {
else
uci -q set openclash.config.redirect_dns=0
fi
if [ "$1" -eq 1 ] && [ "$2" -eq 1 ]; then
uci -q set openclash.config.dnsmasq_cachesize="$(uci -q get dhcp.@dnsmasq[0].cachesize)"
uci -q set dhcp.@dnsmasq[0].cachesize=0
@ -119,7 +119,7 @@ change_dns() {
else
uci -q set openclash.config.cachesize_dns=0
fi
if [ "$1" -eq 1 ] && [ "$ipv6_dns" -eq 1 ] && [ -n "$(ip6tables -t mangle -L 2>&1 | grep -o 'Chain')" ]; then
#dnsmasq answer ipv6
uci -q set openclash.config.dnsmasq_filter_aaaa="$(uci -q get dhcp.@dnsmasq[0].filter_aaaa)"
@ -128,7 +128,7 @@ change_dns() {
else
uci -q set openclash.config.filter_aaaa_dns=0
fi
uci -q commit dhcp
uci -q commit openclash
/etc/init.d/dnsmasq restart >/dev/null 2>&1
@ -144,7 +144,7 @@ revert_dns() {
config_load "openclash"
config_list_foreach "config" "dnsmasq_server" set_dnsmasq_server
}
if [ "$4" == "0" ] || [ -z "$4" ] || [ -z "$(uci -q show dhcp.@dnsmasq[0].server)" ]; then
uci -q set dhcp.@dnsmasq[0].noresolv=0
if [ -n "$5" ] && [ -n "$(grep nameserver $5)" ]; then
@ -179,13 +179,13 @@ EOF
fi
fi
}
[ "$6" -eq 1 ] && {
uci -q set dhcp.@dnsmasq[0].cachesize="$7"
uci -q set openclash.config.cachesize_dns=0
uci -q delete openclash.config.dnsmasq_cachesize
}
[ "$8" -eq 1 ] && {
uci -q set dhcp.@dnsmasq[0].filter_aaaa="$9"
uci -q set openclash.config.filter_aaaa_dns=0
@ -196,7 +196,7 @@ EOF
uci -q set openclash.config.redirect_dns=0
uci -q del openclash.config.dnsmasq_server
}
uci -q commit dhcp
uci -q commit openclash
@ -275,7 +275,7 @@ sub_info_get()
config_get_bool "enabled" "$section" "enabled" "1"
config_get "address" "$section" "address" ""
config_get "name" "$section" "name" ""
if [ "$subscribe_enable" = "1" ]; then
return
fi
@ -283,54 +283,63 @@ sub_info_get()
if [ "$enabled" -eq 0 ]; then
return
fi
if [ -z "$address" ]; then
return
fi
if [ -z "$name" ]; then
RAW_CONFIG_FILE="/etc/openclash/config/config.yaml"
SUB_CONFIG_FILE="/etc/openclash/config/config.yaml"
else
RAW_CONFIG_FILE="/etc/openclash/config/$name.yaml"
SUB_CONFIG_FILE="/etc/openclash/config/$name.yaml"
fi
if [ "$SUB_CONFIG_FILE" != "$2" ]; then
return
fi
uci -q set openclash.config.config_path="$RAW_CONFIG_FILE"
uci -q commit openclash
subscribe_enable=1
}
#配置文件选择
config_choose()
{
if [ -z "$RAW_CONFIG_FILE" ] || [ ! -f "$RAW_CONFIG_FILE" ]; then
CONFIG_NAME=$(ls -lt /etc/openclash/config/ | grep -E '.yaml|.yml' | head -n 1 |awk '{print $9}')
if [ -n "$CONFIG_NAME" ]; then
uci -q set openclash.config.config_path="/etc/openclash/config/$CONFIG_NAME"
uci -q commit openclash
RAW_CONFIG_FILE="/etc/openclash/config/$CONFIG_NAME"
CONFIG_FILE="/etc/openclash/$CONFIG_NAME"
TMP_CONFIG_FILE="/tmp/yaml_config_tmp_$CONFIG_NAME"
fi
fi 2>/dev/null
CONFIG_NAME=$(echo "$RAW_CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
HISTORY_PATH_OLD="/etc/openclash/history/${CONFIG_NAME%.*}"
HISTORY_PATH="/etc/openclash/history/${CONFIG_NAME%.*}.db"
if [ ! -f "$RAW_CONFIG_FILE" ]; then
config_load "openclash"
config_foreach sub_info_get "config_subscribe"
config_foreach sub_info_get "config_subscribe" "$RAW_CONFIG_FILE"
if [ "$subscribe_enable" = "1" ]; then
LOG_OUT "Config File Does Not Exist, You Have Set Subscription Information, Ready To Download..."
nohup /usr/share/openclash/openclash.sh &
del_lock
exit 0
else
LOG_OUT "Error: Config Not Found"
LOG_OUT "【$RAW_CONFIG_FILE】Config File Does Not Exist, You Have Set Subscription Information, Ready To Download..."
nohup /usr/share/openclash/openclash.sh "$RAW_CONFIG_FILE" &
del_lock
exit 0
fi
fi
if [ -z "$RAW_CONFIG_FILE" ] || [ ! -f "$RAW_CONFIG_FILE" ]; then
for file_name in /etc/openclash/config/*
do
if [ -f "$file_name" ]; then
CONFIG_NAME=$(echo "$file_name" |awk -F '/' '{print $5}' 2>/dev/null)
uci -q set openclash.config.config_path="/etc/openclash/config/$CONFIG_NAME"
uci -q commit openclash
RAW_CONFIG_FILE="/etc/openclash/config/$CONFIG_NAME"
CONFIG_FILE="/etc/openclash/$CONFIG_NAME"
TMP_CONFIG_FILE="/tmp/yaml_config_tmp_$CONFIG_NAME"
LOG_OUT "Error: Config Not Found, Switch Config File to【$RAW_CONFIG_FILE】"
break
fi
done
fi 2>/dev/null
if [ ! -f "$RAW_CONFIG_FILE" ]; then
LOG_OUT "Error: Config Not Found"
del_lock
exit 0
fi
CONFIG_NAME=$(echo "$RAW_CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
HISTORY_PATH_OLD="/etc/openclash/history/${CONFIG_NAME%.*}"
HISTORY_PATH="/etc/openclash/history/${CONFIG_NAME%.*}.db"
}
config_check()
@ -362,15 +371,15 @@ yml_other_rules_get()
local enabled config
config_get_bool "enabled" "$section" "enabled" "1"
config_get "config" "$section" "config" ""
if [ "$enabled" = "0" ] || [ "$config" != "$2" ]; then
return
fi
if [ -n "$rule_name" ]; then
return
fi
config_get "rule_name" "$section" "rule_name" ""
}
@ -423,7 +432,7 @@ custom_rule_provider()
if [ "$enabled" = "0" ]; then
return
fi
if [ "$config" = "all" ] || [ "$config" = "$CONFIG_NAME" ]; then
config_set_custom_rule_provider=1
fi
@ -433,22 +442,22 @@ custom_rule_provider()
do_run_mode()
{
en_mode=$(uci -q get openclash.config.en_mode)
if [ "$en_mode" = "fake-ip-tun" ]; then
en_mode_tun="1"
en_mode="fake-ip"
fi
if [ "$en_mode" = "redir-host-tun" ]; then
en_mode_tun="1"
en_mode="redir-host"
fi
if [ "$en_mode" = "redir-host-mix" ]; then
en_mode_tun="2"
en_mode="redir-host"
fi
if [ "$en_mode" = "fake-ip-mix" ]; then
en_mode_tun="2"
en_mode="fake-ip"
@ -461,11 +470,11 @@ do_run_file()
#Some MIPS devices file system cound not use db
source "/etc/openwrt_release"
[ "$small_flash_memory" == "1" ] || [ -n "$(echo $core_version |grep mips)" ] || [ -n "$(echo $DISTRIB_ARCH |grep mips)" ] || [ -n "$(opkg status libc 2>/dev/null |grep 'Architecture' |awk -F ': ' '{print $2}' |grep mips)" ] && mkdir -p /tmp/etc/openclash && CACHE_PATH="/tmp/etc/openclash/cache.db"
[ -f "/etc/openclash/geosite.dat" ] && {
[ -f "/etc/openclash/geosite.dat" ] && {
mv "/etc/openclash/geosite.dat" "/etc/openclash/GeoSite.dat" 2>/dev/null
}
[ -f "/etc/openclash/geoip.dat" ] && {
mv "/etc/openclash/geoip.dat" "/etc/openclash/GeoIP.dat" 2>/dev/null
}
@ -508,22 +517,22 @@ do_run_file()
[ ! -h "/etc/openclash/accelerated-domains.china.conf" ] && mv "/etc/openclash/accelerated-domains.china.conf" "$cndomain_path" 2>/dev/null
mv "/etc/openclash/core/" "/tmp/etc/openclash" 2>/dev/null
fi
rm -rf "/etc/openclash/cache.db" 2>/dev/null
rm -rf "/etc/openclash/clash" 2>/dev/null
if [ "$enable_meta_core" != "1" ]; then
if [ -n "$en_mode_tun" ]; then
ln -s "$tun_core_path" /etc/openclash/clash 2>/dev/null
core_type="TUN"
core_start_log="Tip: Detected The Exclusive Function of The TUN Core, Use TUN Core to Start..."
fi
if [ "$rule_source" != "0" ]; then
config_load "openclash"
config_foreach yml_other_rules_get "other_rules" "$CONFIG_NAME"
fi
config_load "openclash"
config_set_custom_rule_provider=0
for i in "rule_provider_config" "rule_provider_config" "rule_providers" "game_config"; do
@ -545,24 +554,24 @@ do_run_file()
core_type="Meta"
core_start_log="Tip: Detected The Exclusive Function of The Meta Core, Use Meta Core to Start..."
fi
if [ ! -f "/etc/openclash/clash" ] && [ -f "$dev_core_path" ] && [ -z "$core_type" ]; then
ln -s "$dev_core_path" /etc/openclash/clash 2>/dev/null
core_start_log="Tip: No Special Configuration Detected, Use Dev Core to Start..."
fi
if [ ! -f "/etc/openclash/clash" ] && [ -f "$tun_core_path" ] && [ -z "$core_type" ]; then
ln -s "$tun_core_path" /etc/openclash/clash 2>/dev/null
core_type="TUN"
core_start_log="Tip: Detected that the Dev Core is not Installed, Use TUN Core to Start..."
fi
if [ ! -f "/etc/openclash/clash" ] && [ -f "$meta_core_path" ] && [ -z "$core_type" ]; then
ln -s "$meta_core_path" /etc/openclash/clash 2>/dev/null
core_type="Meta"
core_start_log="Tip: Detected that the Dev Core is not Installed, Use Meta Core to Start..."
fi
[ ! -f "$CLASH" ] && {
LOG_OUT "Tip: Detected that the Core is not Installed, Ready to Download..."
rm -rf "/tmp/clash_last_version"
@ -579,7 +588,7 @@ do_run_file()
exit 0
fi
}
[ ! -f "$ipdb_path" ] && {
LOG_OUT "Tip: Detected that the GEOIP Database is not Installed, Ready to Download..."
/usr/share/openclash/openclash_ipdb.sh
@ -587,7 +596,7 @@ do_run_file()
start_fail
fi
}
[ ! -f "$geosite_path" ] && [ "$enable_meta_core" = "1" ] && {
LOG_OUT "Tip: Detected that the GEOSITE Database is not Installed, Ready to Download..."
/usr/share/openclash/openclash_geosite.sh
@ -595,7 +604,7 @@ do_run_file()
start_fail
fi
}
[ ! -f "$geoip_path" ] && [ "$enable_geoip_dat" == "1" ] && {
LOG_OUT "Tip: Detected that the GEOIP Dat is not Installed, Ready to Download..."
/usr/share/openclash/openclash_geoip.sh
@ -603,7 +612,7 @@ do_run_file()
start_fail
fi
}
if [ "$china_ip_route" = "1" ] || [ "$china_ip6_route" = "1" ] || [ "$disable_udp_quic" = "1" ]; then
if [ ! -f "$chnr_path" ] || [ ! -f "$chnr6_path" ]; then
LOG_OUT "Tip: Detected that the Chnroute Cidr or CN Domains List is not Installed, Ready to Download..."
@ -641,15 +650,15 @@ do_run_file()
[ ! -x "$tun_core_path" ] && chmod 4755 "$tun_core_path" 2>/dev/null
[ ! -x "$dev_core_path" ] && chmod 4755 "$dev_core_path" 2>/dev/null
[ ! -x "$meta_core_path" ] && chmod 4755 "$meta_core_path" 2>/dev/null
[ -f "$ipdb_path" ] && [ "$small_flash_memory" = "1" ] && {
ln -s "$ipdb_path" /etc/openclash/Country.mmdb 2>/dev/null
}
[ -f "$geosite_path" ] && [ "$small_flash_memory" = "1" ] && {
ln -s "$geosite_path" /etc/openclash/GeoSite.dat 2>/dev/null
}
[ -f "$geoip_path" ] && [ "$small_flash_memory" = "1" ] && {
ln -s "$geoip_path" /etc/openclash/GeoIP.dat 2>/dev/null
}
@ -657,7 +666,7 @@ do_run_file()
[ -f "$chnr_path" ] && [ "$small_flash_memory" = "1" ] && {
ln -s "$chnr_path" /etc/openclash/china_ip_route.ipset 2>/dev/null
}
[ -f "$chnr6_path" ] && [ "$small_flash_memory" = "1" ] && {
ln -s "$chnr6_path" /etc/openclash/china_ip6_route.ipset 2>/dev/null
}
@ -665,7 +674,7 @@ do_run_file()
[ -f "$cndomain_path" ] && [ "$small_flash_memory" = "1" ] && {
ln -s "$cndomain_path" /etc/openclash/accelerated-domains.china.conf 2>/dev/null
}
#Restore history cache
if [ -f "$HISTORY_PATH" ] && [ -f "$HISTORY_PATH_OLD" ]; then
if [ "$(date -r $HISTORY_PATH +%s)" -ge "$(date -r $HISTORY_PATH_OLD +%s)" ]; then
@ -683,7 +692,7 @@ do_run_file()
cp "$HISTORY_PATH_OLD" "$CACHE_PATH_OLD" 2>/dev/null
fi
fi
else
else
if [ -f "$HISTORY_PATH" ]; then
cmp -s "$CACHE_PATH" "$HISTORY_PATH"
if [ "$?" -ne "0" ]; then
@ -701,7 +710,7 @@ do_run_file()
fi
fi
fi
if [ "$CACHE_PATH" == "/tmp/etc/openclash/cache.db" ]; then
[ ! -f "$CACHE_PATH" ] && touch "$CACHE_PATH"
ln -s "$CACHE_PATH" /etc/openclash/cache.db 2>/dev/null
@ -719,12 +728,12 @@ do_run_file()
start_fail
fi
#创建原始备份
if [ ! -f "$2" ]; then
cp "$1" "$2"
fi
#保存启动内核类型
uci -q set openclash.config.core_type="$core_type"
uci -q commit openclash
@ -810,7 +819,7 @@ raw_config_start()
dns_port=$(ruby_read "$CONFIG_FILE" "['dns']['listen'].split(':')[1]")
en_mode=$(ruby_read "$CONFIG_FILE" "['dns']['enhanced-mode']")
proxy_port=$(ruby_read "$CONFIG_FILE" "['redir-port']")
if [ -z "$dns_port" ] || [ -z "$en_mode" ] || [ -z "$proxy_port" ]; then
if [ -z "$dns_port" ]; then
LOG_OUT "Error: Get DNS 'listen' Option Error, OpenClash Can Not Start With Raw Config File"
@ -823,15 +832,15 @@ raw_config_start()
fi
start_fail
fi
start_run_core
check_core_status
if ! pidof clash >/dev/null; then
LOG_OUT "Error: OpenClash Can Not Start, Please Check The Error Info And Try Again!"
start_fail
fi
if [ "$en_mode" = "redir-host" ]; then
case $en_mode_tun in
"1")
@ -855,16 +864,16 @@ raw_config_start()
uci -q set openclash.config.en_mode=fake-ip
esac
fi
dase=$(ruby_read "$CONFIG_FILE" "['secret']")
uci -q set openclash.config.dashboard_password="$dase"
cn_port=$(ruby_read "$CONFIG_FILE" "['external-controller'].split(':')[1]")
uci -q set openclash.config.cn_port="$cn_port"
uci -q set openclash.config.proxy_port="$proxy_port"
uci -q set openclash.config.restricted_mode=1
uci commit openclash
}
@ -975,7 +984,7 @@ firewall_rule_exclude()
if [ $p == udp ]; then e_udp=true; fi
if [ $p == all ]; then e_tcp=true; e_udp=true; fi
done
if [ -z "$proto" ]; then e_tcp=true; e_udp=true; fi
if ! $e_udp && ! $e_tcp ; then
@ -986,7 +995,7 @@ firewall_rule_exclude()
LOG_OUT "Warning: Because there is a port range【$dest_port】in the firewall rule settings【$name】auto bypassing may cause the normal connection of the client not to reach the core, if necessary, please add your own in the access control!"
return
fi
if [ -n "$FW4" ]; then
if [ -z "$family" ] || [ "$family" == "ipv4" ]; then
if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 2 ]; then
@ -1029,7 +1038,7 @@ firewall_rule_exclude()
done
fi
fi
if [ "$ipv6_enable" -eq 1 ]; then
if [ -z "$family" ] || [ "$family" == "ipv6" ]; then
for i in $dest_port; do
@ -1055,7 +1064,7 @@ firewall_rule_exclude()
else
dest_port=$(echo $dest_port |sed "s/-/:/g" 2>/dev/null)
dest_ip=$(echo $dest_ip |sed "s/ /,/g" 2>/dev/null)
if [ -z "$family" ] || [ "$family" == "ipv4" ]; then
if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 2 ]; then
for i in $dest_port; do
@ -1097,7 +1106,7 @@ firewall_rule_exclude()
done
fi
fi
if [ "$ipv6_enable" -eq 1 ] && [ -n "$(ip6tables -t mangle -L 2>&1 | grep -o 'Chain')" ]; then
if [ -z "$family" ] || [ "$family" == "ipv6" ]; then
for i in $dest_port; do
@ -1150,13 +1159,13 @@ firewall_redirect_exclude()
if [ $p == udp ]; then e_udp=true; fi
if [ $p == all ]; then e_tcp=true; e_udp=true; fi
done
if [ -z "$proto" ]; then e_tcp=true; e_udp=true; fi
if ! $e_udp && ! $e_tcp ; then
return
fi
if [ -n "$FW4" ]; then
if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 2 ]; then
if $e_tcp ; then
@ -1182,7 +1191,7 @@ firewall_redirect_exclude()
fi
fi
fi
if [ "$ipv6_enable" -eq 1 ]; then
if $e_tcp ; then
if [ -n "$dest_ip" ]; then
@ -1226,7 +1235,7 @@ firewall_redirect_exclude()
fi
fi
fi
if [ "$ipv6_enable" -eq 1 ] && [ -n "$(ip6tables -t mangle -L 2>&1 | grep -o 'Chain')" ]; then
if $e_tcp ; then
if [ -n "$dest_ip" ]; then
@ -1247,23 +1256,30 @@ firewall_redirect_exclude()
set_tun_tap()
{
#启动TUN
local type=$1
if [ -z "$1" ]; then
ip_="ip"
else
ip_="ip -6"
fi
TUN_WAIT=0
TUN_RESTART=1
if [ -n "$(pidof clash)" ] && [ -n "$(ip rule show |grep "fwmark 0x162 lookup 354")" ]; then
ip -6 rule del oif utun table 2022 >/dev/null 2>&1
ip -6 route del default dev utun table 2022 >/dev/null 2>&1
if [ -n "$(pidof clash)" ] && [ -n "$1" ] && [ "$(ip -6 route list |grep utun |wc -l)" -ne 2 ] && [ -n "$(ifconfig utun)" ]; then
if [ "$enable_meta_core" = "1" ]; then
ip -6 addr add fdfe:dcba:9876::1/126 dev utun >/dev/null 2>&1
ip -6 route add fdfe:dcba:9876::/126 dev utun proto kernel metric 256 pref medium >/dev/null 2>&1
ip -6 route add fe80::/64 dev utun proto kernel metric 256 pref medium >/dev/null 2>&1
fi
ip -6 route replace default dev utun table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
ip -6 rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
return
fi
#prevent lost when v6 utun address added
if [ -n "$(pidof clash)" ] && [ -z "$(ip route list |grep utun)" ] && [ -n "$(ifconfig utun)" ]; then
route add -net "$fakeip_range" dev utun >/dev/null 2>&1
ip route replace default dev utun table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
ip rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
fi
$ip_ link set utun up
@ -1293,7 +1309,7 @@ set_tun_tap()
fi
fi
if [ -n "$1" ]; then
if [ -n "$1" ] && [ "$enable_meta_core" = "1" ]; then
ip -6 rule del oif utun table 2022 >/dev/null 2>&1
ip -6 route del default dev utun table 2022 >/dev/null 2>&1
fi
@ -1611,7 +1627,7 @@ if [ -n "$FW4" ]; then
fi
fi
nft add rule inet fw4 openclash ip protocol tcp counter redirect to "$proxy_port"
nft 'add rule inet fw4 dstnat ip protocol tcp counter jump openclash'
nft 'add rule inet fw4 dstnat meta nfproto {ipv4} ip protocol tcp counter jump openclash'
if [ -z "$en_mode_tun" ]; then
#Google dns
nft insert rule inet fw4 dstnat position 0 ip daddr { 8.8.8.8, 8.8.4.4 } tcp dport 53 counter redirect to "$proxy_port" comment \"OpenClash Google DNS Hijack\"
@ -1656,8 +1672,8 @@ if [ -n "$FW4" ]; then
nft 'add rule inet fw4 openclash_mangle ip protocol udp counter jump openclash_upnp'
nft add rule inet fw4 openclash_mangle meta l4proto { udp } mark set "$PROXY_FWMARK" tproxy ip to 127.0.0.1:"$tproxy_port" counter accept
nft 'add rule inet fw4 mangle_prerouting ip protocol udp counter jump openclash_mangle'
nft 'add rule inet fw4 mangle_prerouting meta nfproto {ipv4} ip protocol udp counter jump openclash_mangle'
elif [ "$en_mode" = "fake-ip" ]; then
modprobe nft_tproxy >/dev/null 2>&1
ip rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE"
@ -1666,13 +1682,13 @@ if [ -n "$FW4" ]; then
nft 'flush chain inet fw4 openclash_mangle'
nft 'add rule inet fw4 openclash_mangle meta l4proto { udp } iifname lo counter return'
nft add rule inet fw4 openclash_mangle meta l4proto { udp } ip daddr { "$fakeip_range" } mark set "$PROXY_FWMARK" tproxy ip to 127.0.0.1:"$tproxy_port" counter accept 2>/dev/null
nft 'add rule inet fw4 mangle_prerouting ip protocol udp counter jump openclash_mangle'
nft 'add rule inet fw4 mangle_prerouting meta nfproto {ipv4} ip protocol udp counter jump openclash_mangle'
if [ "$router_self_proxy" = "1" ] || ([ "$enable_redirect_dns" != "2" ] && [ "$en_mode" = "fake-ip" ]); then
nft 'add chain inet fw4 openclash_mangle_output'
nft 'flush chain inet fw4 openclash_mangle_output'
nft add rule inet fw4 openclash_mangle_output meta l4proto { udp } ip daddr { "$fakeip_range" } mark set "$PROXY_FWMARK" counter
nft 'add rule inet fw4 mangle_output ip protocol udp counter jump openclash_mangle_output'
nft 'add rule inet fw4 mangle_output meta nfproto {ipv4} ip protocol udp counter jump openclash_mangle_output'
fi
fi
@ -1681,7 +1697,7 @@ if [ -n "$FW4" ]; then
nft insert rule inet fw4 input position 0 udp dport 443 ip daddr != @china_ip_route counter reject comment \"OpenClash QUIC REJECT\"
fi
fi
if [ "$router_self_proxy" = "1" ] || ([ "$enable_redirect_dns" != "2" ] && [ "$en_mode" = "fake-ip" ]); then
nft 'add chain inet fw4 openclash_output'
nft 'flush chain inet fw4 openclash_output'
@ -1706,7 +1722,7 @@ if [ -n "$FW4" ]; then
nft add rule inet fw4 openclash_output ip protocol tcp skuid != 65534 counter redirect to "$proxy_port"
fi
nft 'add chain inet fw4 nat_output { type nat hook output priority -1; }'
nft 'add rule inet fw4 nat_output ip protocol tcp counter jump openclash_output'
nft 'add rule inet fw4 nat_output meta nfproto {ipv4} ip protocol tcp counter jump openclash_output'
fi
fi
@ -1750,7 +1766,7 @@ if [ -n "$FW4" ]; then
fi
nft add rule inet fw4 openclash_mangle_output tcp dport { 0-65535 } skuid != 65534 meta mark set "$PROXY_FWMARK" counter
fi
nft 'add rule inet fw4 mangle_output meta l4proto {tcp,udp} counter jump openclash_mangle_output'
nft 'add rule inet fw4 mangle_output meta nfproto {ipv4} meta l4proto {tcp,udp} counter jump openclash_mangle_output'
fi
nft 'add chain inet fw4 openclash_mangle'
@ -1774,7 +1790,7 @@ if [ -n "$FW4" ]; then
nft 'add rule inet fw4 openclash_mangle ether saddr != @lan_ac_white_macs counter return'
nft 'add rule inet fw4 openclash_mangle ip saddr != @lan_ac_white_ips counter return'
fi
if [ "$en_mode" = "redir-host" ]; then
nft 'add rule inet fw4 openclash_mangle meta l4proto {tcp,udp} th dport != @common_ports counter return'
fi
@ -1787,9 +1803,9 @@ if [ -n "$FW4" ]; then
fi
nft 'add rule inet fw4 openclash_mangle ip protocol udp counter jump openclash_upnp'
nft add rule inet fw4 openclash_mangle meta l4proto {tcp,udp} th dport { 0-65535 } mark set "$PROXY_FWMARK" counter
if [ "$en_mode_tun" -eq 1 ]; then
nft 'insert rule inet fw4 mangle_prerouting position 0 meta l4proto {tcp,udp} counter jump openclash_mangle'
nft 'insert rule inet fw4 mangle_prerouting position 0 meta nfproto {ipv4} meta l4proto {tcp,udp} counter jump openclash_mangle'
else
if [ "$enable_redirect_dns" -eq 1 ]; then
nft 'insert rule inet fw4 mangle_prerouting position 0 meta nfproto {ipv4} tcp dport 53 counter jump openclash_dns_hijack'
@ -1803,7 +1819,7 @@ if [ -n "$FW4" ]; then
fi
nft add rule inet fw4 openclash_dns_hijack meta nfproto {ipv4} tcp dport 53 mark set "$PROXY_FWMARK" comment \"OpenClash TCP DNS Hijack\" counter
fi
nft 'insert rule inet fw4 mangle_prerouting position 0 ip protocol udp counter jump openclash_mangle'
nft 'insert rule inet fw4 mangle_prerouting position 0 meta nfproto {ipv4} ip protocol udp counter jump openclash_mangle'
fi
if [ "$enable_redirect_dns" -eq 2 ]; then
@ -1816,7 +1832,7 @@ if [ -n "$FW4" ]; then
#TUN FORWORD
nft insert rule inet fw4 forward position 0 meta l4proto {tcp,udp} oifname utun counter accept comment \"OpenClash TUN Forward\"
#quic
if [ "$disable_udp_quic" -eq 1 ]; then
nft insert rule inet fw4 forward position 0 oifname utun udp dport 443 ip daddr != @china_ip_route counter reject comment \"OpenClash QUIC REJECT\"
@ -1906,7 +1922,7 @@ if [ -n "$FW4" ]; then
if [ "$enable_redirect_dns" != "2" ]; then
mkdir -p ${DNSMASQ_CONF_DIR}
echo "add set inet fw4 china_ip6_route_pass { type ipv6_addr; flags interval; auto-merge; }" >>/tmp/openclash_china_ip6_route_pass.list
[ -z `(awk '!/^$/&&!/^#/&&!/^(\*?\.?)*[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})*$/{printf(" %s,'" "'\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute6_pass.list)` ] || {
echo "define china_ip6_route_pass = {" >/tmp/openclash_china_ip6_route_pass.list
@ -1938,7 +1954,7 @@ if [ -n "$FW4" ]; then
fi
fi
fi
#local
nft 'add set inet fw4 localnetwork6 { type ipv6_addr; flags interval; auto-merge; }'
#nft 'delete set inet fw4 localnetwork6'
@ -1956,7 +1972,7 @@ if [ -n "$FW4" ]; then
nft add element inet fw4 localnetwork6 { "$wan_ip6" }
done
fi
#Google dns
nft insert rule inet fw4 dstnat position 0 ip6 daddr { 2001:4860:4860::8888, 2001:4860:4860::8844 } tcp dport 53 counter accept comment \"OpenClash Google DNS Hijack\"
@ -2013,7 +2029,7 @@ if [ -n "$FW4" ]; then
nft add rule inet fw4 openclash_output_v6 meta nfproto {ipv6} skuid != 65534 tcp dport { 0-65535 } mark set "$PROXY_FWMARK" tproxy ip6 to :"$tproxy_port" counter accept comment \"OpenClash TCP Tproxy\"
fi
nft 'add chain inet fw4 nat_output { type nat hook output priority -1; }'
nft 'add rule inet fw4 nat_output ip protocol tcp counter jump openclash_output_v6'
nft 'add rule inet fw4 nat_output meta nfproto {ipv6} ip protocol tcp counter jump openclash_output_v6'
fi
fi
@ -2092,7 +2108,7 @@ if [ -n "$FW4" ]; then
fi
nft 'add rule inet fw4 mangle_prerouting meta nfproto {ipv6} counter jump openclash_mangle_v6'
#route
if [ "$ipv6_mode" -ne 2 ]; then
if [ "$enable_v6_udp_proxy" -eq 1 ] || [ "$ipv6_mode" -eq 0 ]; then
@ -2108,7 +2124,7 @@ if [ -n "$FW4" ]; then
if [ "$disable_udp_quic" -eq 1 ]; then
nft insert rule inet fw4 input position 0 udp dport 443 ip6 daddr != @china_ip6_route counter reject comment \"OpenClash QUIC REJECT\"
fi
#bypass gateway compatible
if [ "$bypass_gateway_compatible" -eq 1 ]; then
#nft 'delete chain inet fw4 openclash_post_v6'
@ -2430,7 +2446,7 @@ if [ -z "$FW4" ]; then
iptables -t mangle -A openclash -p udp -j openclash_upnp >/dev/null 2>&1
iptables -t mangle -A openclash -p udp -j TPROXY --on-port "$tproxy_port" --tproxy-mark "$PROXY_FWMARK"
iptables -t mangle -A PREROUTING -p udp -j openclash
elif [ "$en_mode" = "fake-ip" ]; then
modprobe xt_TPROXY >/dev/null 2>&1
ip rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE"
@ -2455,7 +2471,7 @@ if [ -z "$FW4" ]; then
iptables -I INPUT -p udp --dport 443 -m comment --comment "OpenClash QUIC REJECT" -m set ! --match-set china_ip_route dst -j REJECT >/dev/null 2>&1
fi
fi
if [ "$router_self_proxy" = "1" ] || ([ "$enable_redirect_dns" != "2" ] && [ "$en_mode" = "fake-ip" ]); then
iptables -t nat -N openclash_output
iptables -t nat -F openclash_output
@ -2529,7 +2545,7 @@ if [ -z "$FW4" ]; then
iptables -t mangle -A OUTPUT -j openclash_output
fi
fi
iptables -t mangle -N openclash
iptables -t mangle -F openclash
iptables -t mangle -N openclash_dns_hijack
@ -2565,7 +2581,7 @@ if [ -z "$FW4" ]; then
iptables -t mangle -A openclash -p udp -j openclash_upnp >/dev/null 2>&1
iptables -t mangle -A openclash -j MARK --set-mark "$PROXY_FWMARK"
if [ "$en_mode_tun" -eq 1 ]; then
iptables -t mangle -I PREROUTING -j openclash
else
@ -2594,7 +2610,7 @@ if [ -z "$FW4" ]; then
#TUN FORWORD
iptables -I FORWARD -m comment --comment "OpenClash TUN Forward" -o utun -j ACCEPT
#quic
if [ "$disable_udp_quic" -eq 1 ]; then
iptables -I FORWARD -p udp --dport 443 -o utun -m comment --comment "OpenClash QUIC REJECT" -m set ! --match-set china_ip_route dst -j REJECT >/dev/null 2>&1
@ -2696,7 +2712,7 @@ if [ -z "$FW4" ]; then
sed -i "s/china_ip_route_pass/china_ip6_route_pass/g" ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf
fi
fi
#local
ipset create localnetwork6 hash:net family inet6
if [ -f "/etc/openclash/custom/openclash_custom_localnetwork_ipv6.list" ]; then
@ -2725,7 +2741,7 @@ if [ -z "$FW4" ]; then
ipset add localnetwork6 "$wan_ip6"
done
fi
#Google dns
ip6tables -t nat -I PREROUTING -m comment --comment "OpenClash Google DNS Hijack" -p tcp -d 2001:4860:4860::8888 --dport 53 -j ACCEPT
ip6tables -t nat -I PREROUTING -m comment --comment "OpenClash Google DNS Hijack" -p tcp -d 2001:4860:4860::8844 --dport 53 -j ACCEPT
@ -2811,7 +2827,7 @@ if [ -z "$FW4" ]; then
fi
fi
fi
#TProxy & TUN
if [ "$ipv6_mode" -ne 1 ]; then
if [ "$ipv6_mode" -eq 0 ]; then
@ -2869,7 +2885,7 @@ if [ -z "$FW4" ]; then
if [ "$disable_udp_quic" -eq 1 ]; then
ip6tables -I INPUT -p udp --dport 443 -m comment --comment "OpenClash QUIC REJECT" -m set ! --match-set china_ip6_route dst -j REJECT >/dev/null 2>&1
fi
#bypass gateway compatible
if [ "$bypass_gateway_compatible" -eq 1 ]; then
ip6tables -t nat -N openclash_post
@ -2894,7 +2910,7 @@ if [ -z "$FW4" ]; then
ip6tables -t filter -I FORWARD -m set --match-set lan_block_google_dns_ipv6s src -m set --match-set openclash_google_dns_ipv6s dst -j REJECT >/dev/null 2>&1
ip6tables -t filter -I FORWARD -m set --match-set lan_block_google_dns_macs src -m set --match-set openclash_google_dns_ipv6s dst -j REJECT >/dev/null 2>&1
fi
#intranet allowed
if [ "$intranet_allowed" -eq 1 ]; then
wan6_ints=$(ip6tables-save -t filter |grep -e "-j zone_wan_input" 2>/dev/null |awk '{for (i=1;i<=NF;i++) {if ($i ~ /-i/) {print $(i+1)}}}' 2>/dev/null)
@ -2937,10 +2953,10 @@ revert_firewall()
ip rule del fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
ip route del local 0.0.0.0/0 dev lo table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
ip -6 rule del fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
ip -6 route del local ::/0 dev lo table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
#TUN
ip route del default dev utun table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
ip rule del fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
@ -2952,6 +2968,7 @@ revert_firewall()
ip -6 rule del fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
ip -6 rule del oif utun table 2022 >/dev/null 2>&1
ip -6 route del default dev utun table 2022 >/dev/null 2>&1
ip -6 route del fdfe:dcba:9876::/126 dev utun proto kernel metric 256 >/dev/null 2>&1
ip -6 link set dev utun down >/dev/null 2>&1
ip -6 tuntap del utun mode tun >/dev/null 2>&1
@ -2981,7 +2998,7 @@ revert_firewall()
fi
done
done >/dev/null 2>&1
for chain in "openclash" "openclash_output" "openclash_post" "openclash_dns_hijack" "openclash_wan_input" "openclash_dns_redirect" "openclash_upnp"; do
iptables -t nat -F $chain
iptables -t nat -X $chain
@ -3081,6 +3098,7 @@ get_config()
find_process_mode=$(uci -q get openclash.config.find_process_mode || echo 0)
upnp_lease_file=$(uci -q get upnpd.config.upnp_lease_file)
global_client_fingerprint=$(uci -q get openclash.config.global_client_fingerprint || echo "0")
enable_unified_delay=$(uci -q get openclash.config.enable_unified_delay || echo "0")
[ -z "$dns_port" ] && dns_port=7874 && uci -q set openclash.config.dns_port=7874
uci -q set openclash.config.restricted_mode=0 && uci -q commit openclash
}
@ -3094,33 +3112,33 @@ start()
LOG_OUT "OpenClash Start Running..."
config_choose
do_run_mode
LOG_OUT "Step 1: Get The Configuration..."
get_config
LOG_OUT "Step 2: Check The Components..."
#检查文件是否存在
do_run_file "$RAW_CONFIG_FILE" "$BACKUP_FILE"
#快速启动判断
check_run_quick
if ! $quick_start; then
LOG_OUT "Step 3: Modify The Config File..."
config_check
/usr/share/openclash/yml_change.sh 2>/dev/null "$en_mode" "$da_password" "$cn_port" "$proxy_port" "$TMP_CONFIG_FILE" "$ipv6_enable" "$http_port" "$socks_port" "$log_level" "$proxy_mode" "$en_mode_tun" "$stack_type" "$dns_port" "$mixed_port" "$tproxy_port" "$ipv6_dns" "$store_fakeip" "$stream_domains_prefetch" "$enable_meta_core" "$enable_meta_sniffer" "$enable_geoip_dat" "$geodata_loader" "$enable_meta_sniffer_custom" "$interface_name" "$enable_tcp_concurrent" "$core_type" "$append_default_dns" "$enable_meta_sniffer_pure_ip" "$find_process_mode" "$fakeip_range" "$global_client_fingerprint" "$ipv6_mode" "$stack_type_v6"
/usr/share/openclash/yml_change.sh 2>/dev/null "$en_mode" "$da_password" "$cn_port" "$proxy_port" "$TMP_CONFIG_FILE" "$ipv6_enable" "$http_port" "$socks_port" "$log_level" "$proxy_mode" "$en_mode_tun" "$stack_type" "$dns_port" "$mixed_port" "$tproxy_port" "$ipv6_dns" "$store_fakeip" "$stream_domains_prefetch" "$enable_meta_core" "$enable_meta_sniffer" "$enable_geoip_dat" "$geodata_loader" "$enable_meta_sniffer_custom" "$interface_name" "$enable_tcp_concurrent" "$core_type" "$append_default_dns" "$enable_meta_sniffer_pure_ip" "$find_process_mode" "$fakeip_range" "$global_client_fingerprint" "$ipv6_mode" "$stack_type_v6" "$enable_unified_delay"
/usr/share/openclash/yml_rules_change.sh 2>/dev/null "$rule_source" "$enable_custom_clash_rules" "$TMP_CONFIG_FILE" "$enable_rule_proxy" "$CONFIG_NAME" "$router_self_proxy" "$lan_ip" "$proxy_port" "$tproxy_port" "$enable_meta_core" "$enable_redirect_dns" "$fakeip_range" "$en_mode"
/usr/share/openclash/openclash_custom_domain_dns.sh >/dev/null 2>&1
#Custom overwrite
if [ -f "/etc/openclash/custom/openclash_custom_overwrite.sh" ]; then
chmod +x /etc/openclash/custom/openclash_custom_overwrite.sh >/dev/null 2>&1
/etc/openclash/custom/openclash_custom_overwrite.sh 2>/dev/null "$TMP_CONFIG_FILE"
/etc/openclash/custom/openclash_custom_overwrite.sh 2>/dev/null "$TMP_CONFIG_FILE"
fi
fi
LOG_OUT "Step 4: Start Running The Clash Core..."
start_run_core
LOG_OUT "Step 5: Check The Core Status..."
check_core_status
@ -3131,13 +3149,12 @@ start()
yml_provider_check "$CONFIG_FILE" "rule-providers" "payload"
fi
try_restore_start
LOG_OUT "Step 7: Set Firewall Rules..."
set_firewall
LOG_OUT "Step 8: Restart Dnsmasq..."
change_dns "$enable_redirect_dns" "$disable_masq_cache"
LOG_OUT "Step 9: Add Cron Rules, Start Daemons..."
add_cron
if [ "$(uci -q get openclash.config.restricted_mode)" != "1" ]; then
@ -3174,7 +3191,7 @@ stop()
for watchdog_pid in $watchdog_pids; do
kill -9 "$watchdog_pid" >/dev/null 2>&1
done >/dev/null 2>&1
streaming_unlock_pids=$(unify_ps_pids "openclash_streaming_unlock.lua")
for streaming_unlock_pid in $streaming_unlock_pids; do
kill -9 "$streaming_unlock_pid" >/dev/null 2>&1
@ -3186,7 +3203,7 @@ stop()
kill -9 "$openclash_pid" >/dev/null 2>&1
fi
done >/dev/null 2>&1
LOG_OUT "Step 4: Close The Clash Core Process..."
if [ "$enable" != "1" ]; then
kill_clash
@ -3225,7 +3242,7 @@ stop()
del_lock
LOG_OUT "OpenClash Already Stop!"
fi
del_cron
rm -rf /tmp/yaml_* >/dev/null 2>&1
rm -rf $START_LOG >/dev/null 2>&1

View File

@ -1,2 +1,4 @@
#baidu.com
#114.114.114.114
#114.114.114.114
##解决绕过大陆后谷歌商店无法更新
services.googleapis.cn

View File

@ -0,0 +1,130 @@
# 针对部分网站显示IP归属地的分流规则
# anti-ip-attribution rule-provider.yaml v0.3.0 b38fca55691235e8b59879093163d971ce803e2e
# https://github.com/lwd-temp/anti-ip-attribution
# 适用于Clash的Rule Provider功能详见https://lancellc.gitbook.io/clash/clash-config-file/rule-provider
payload:
- DOMAIN-SUFFIX,biliapi.net
- DOMAIN,api.bilibili.com
- DOMAIN,api.bilibili.tv
- DOMAIN,app.bilibili.com
- DOMAIN-SUFFIX,biliapi.com
- DOMAIN,api.live.bilibili.com
- DOMAIN,api.vc.bilibili.com
- DOMAIN,passport.bilibili.com
- DOMAIN,live-trace.bilibili.com
- DOMAIN,message.bilibili.com
- DOMAIN,cm.bilibili.com
- DOMAIN-SUFFIX,bilibili.com
- DOMAIN-SUFFIX,im9.com
- DOMAIN-SUFFIX,acg.tv
- DOMAIN-SUFFIX,biligame.com
- IP-CIDR,203.107.1.0/24,REJECT
- DOMAIN-SUFFIX,weibo.cn
- DOMAIN-SUFFIX,weibo.com
- DOMAIN-SUFFIX,weibocdn.com
- DOMAIN-KEYWORD,weibo
- DOMAIN,tieba.baidu.com
- DOMAIN,tbmsg.baidu.com
- DOMAIN,tb5.bdstatic.com
- DOMAIN,fclog.baidu.com
- DOMAIN,gsp0.baidu.com
- DOMAIN,hm.baidu.com
- DOMAIN,www.baidu.com
- DOMAIN,tiebac.baidu.com
- IP-CIDR,180.76.76.0/24
- DOMAIN,httpsdns.baidu.com
- DOMAIN,c.tieba.baidu.com
- DOMAIN,httpdns.baidu.com
- DOMAIN,httpdns.baidubce.com
- DOMAIN,szshort.weixin.qq.com
- DOMAIN,szextshort.weixin.qq.com
- DOMAIN,szminorshort.weixin.qq.com
- DOMAIN,mp.weixin.qq.com
- DOMAIN-SUFFIX,zhihu.com
- IP-CIDR,103.41.167.0/24
- IP-CIDR,118.89.204.198/23,REJECT
- IP-CIDR6,2402:4e00:1200:ed00:0:9089:6dac:96b6/40,REJECT
- DOMAIN-KEYWORD,core-c-lq
- DOMAIN-KEYWORD,core-lq
- DOMAIN-KEYWORD,normal-c-lq
- DOMAIN-KEYWORD,normal-lq
- DOMAIN-KEYWORD,search-quic-lq
- DOMAIN-KEYWORD,search-lq
- DOMAIN-SUFFIX,zijieapi.com,DIRECT
- DOMAIN-SUFFIX,ecombdapi.com,DIRECT
- DOMAIN-KEYWORD,-normal-hl
- DOMAIN-KEYWORD,-normal-c-hl
- DOMAIN-KEYWORD,-core-c-hl
- DOMAIN-KEYWORD,-normal-lf
- DOMAIN-KEYWORD,-normal-c-lf
- DOMAIN-KEYWORD,-core-c-lf
- DOMAIN,sso.douyin.com
- DOMAIN,www.douyin.com
- DOMAIN-SUFFIX,snssdk.com
- DOMAIN-SUFFIX,toutiaoapi.com
- DOMAIN-SUFFIX,gifshow.com
- DOMAIN-SUFFIX,ksapisrv.com
- DOMAIN-SUFFIX,xiaohongshu.com
- DOMAIN,keylol.com
- DOMAIN-SUFFIX,ixigua.com
- DOMAIN,www.wenshushu.cn
- IP-CIDR,119.29.29.98/32,REJECT
- DOMAIN,frodo.douban.com
- DOMAIN,www.douban.com
- DOMAIN,api.coolapk.com
- DOMAIN,api.taptapdada.com
- DOMAIN,god.gameyw.netease.com
- DOMAIN-SUFFIX,huya.com
- DOMAIN-SUFFIX,dongqiudi.com
- DOMAIN,ngabbs.com
- DOMAIN,api.vip.miui.com
- DOMAIN-SUFFIX,music.163.com
- DOMAIN,nstool.netease.com
- DOMAIN,wanproxy.127.net
- DOMAIN,mam.netease.com
- DOMAIN,dt.netease.im
- DOMAIN,api.iplay.163.com
- DOMAIN,api.k.163.com
- DOMAIN,lbs.netease.im
- DOMAIN,wannos.127.net
- DOMAIN,ac.dun.163.com
- DOMAIN-SUFFIX,music.126.net
- DOMAIN-SUFFIX,laiqukankan.com
- DOMAIN-SUFFIX,music.ntes53.netease.com
- IP-CIDR,101.71.154.241/32
- IP-CIDR,103.126.92.132/32
- IP-CIDR,103.126.92.133/32
- IP-CIDR,112.13.119.18/32
- IP-CIDR,112.13.122.4/32
- IP-CIDR,115.236.118.34/32
- IP-CIDR,115.236.121.4/32
- IP-CIDR,45.254.48.1/32
- IP-CIDR,59.111.160.195/32
- IP-CIDR,59.111.19.33/32
- IP-CIDR,59.111.19.53/32
- DOMAIN-SUFFIX,hls3-akm.douyucdn.cn,DIRECT
- DOMAIN-SUFFIX,hlsa-akm.douyucdn.cn,DIRECT
- DOMAIN-SUFFIX,hls1a-akm.douyucdn.cn,DIRECT
- DOMAIN-SUFFIX,hls3a-akm.douyucdn.cn,DIRECT
- DOMAIN-SUFFIX,vplay1a.douyucdn.cn,DIRECT
- DOMAIN-SUFFIX,vplay3a.douyucdn.cn,DIRECT
- DOMAIN-SUFFIX,ws-tct.douyucdn.cn,DIRECT
- DOMAIN-SUFFIX,akm-tct.douyucdn.cn,DIRECT
- DOMAIN-SUFFIX,tx2play1.douyucdn.cn,DIRECT
- DOMAIN-SUFFIX,tc-tct1.douyucdn.cn,DIRECT
- DOMAIN-SUFFIX,wsproxy.douyu.com,DIRECT
- DOMAIN-SUFFIX,danmuproxy.douyu.com,DIRECT
- DOMAIN-SUFFIX,img.douyucdn.cn,DIRECT
- DOMAIN-SUFFIX,douyucdn.cn
- DOMAIN-SUFFIX,douyu.com
- DOMAIN,bbs-api.mihoyo.com
- DOMAIN,bbs-api.miyoushe.com
- DOMAIN-SUFFIX,douban.com
- IP-CIDR,49.233.242.15/32
- IP-CIDR,81.70.124.99/32
- IP-CIDR,81.70.125.19/32
- IP-CIDR,140.143.177.206/32
- DOMAIN,api.xiaoheihe.cn
- DOMAIN,y.qq.com,DIRECT
- DOMAIN-SUFFIX,y.qq.com
- DOMAIN,zonai.skland.com

View File

@ -104,7 +104,13 @@ fi
config_cus_up()
{
if [ -z "$CONFIG_PATH" ]; then
CONFIG_PATH="/etc/openclash/config/$(ls -lt /etc/openclash/config/ | grep -E '.yaml|.yml' | head -n 1 |awk '{print $9}')"
for file_name in /etc/openclash/config/*
do
if [ -f "$file_name" ]; then
CONFIG_PATH=$file_name
break
fi
done
uci -q set openclash.config.config_path="$CONFIG_PATH"
uci commit openclash
fi
@ -450,6 +456,7 @@ EOF
if [ "${PIPESTATUS[0]}" -eq 0 ] && [ -s "$CFG_FILE" ]; then
#prevent ruby unexpected error
sed -i -E 's/protocol-param: ([^,'"'"'"''}( *#)\n\r]+)/protocol-param: "\1"/g' "$CFG_FILE" 2>/dev/null
sed -i '/^ \{0,\}enhanced-mode:/d' "$CFG_FILE" >/dev/null 2>&1
config_test
if [ $? -ne 0 ]; then
LOG_OUT "Error: Config File Tested Faild, Please Check The Log Infos!"
@ -585,6 +592,10 @@ sub_info_get()
CONFIG_FILE="/etc/openclash/config/$name.yaml"
BACKPACK_FILE="/etc/openclash/backup/$name.yaml"
fi
if [ -n "$2" ] && [ "$2" != "$CONFIG_FILE" ]; then
return
fi
if [ ! -z "$keyword" ] || [ ! -z "$ex_keyword" ]; then
config_list_foreach "$section" "keyword" server_key_match "keyword"
@ -634,6 +645,7 @@ sub_info_get()
if [ "${PIPESTATUS[0]}" -eq 0 ] && [ -s "$CFG_FILE" ]; then
#prevent ruby unexpected error
sed -i -E 's/protocol-param: ([^,'"'"'"''}( *#)\n\r]+)/protocol-param: "\1"/g' "$CFG_FILE" 2>/dev/null
sed -i '/^ \{0,\}enhanced-mode:/d' "$CFG_FILE" >/dev/null 2>&1
config_test
if [ $? -ne 0 ]; then
LOG_OUT "Error: Config File Tested Faild, Please Check The Log Infos!"
@ -674,7 +686,7 @@ sub_info_get()
#分别获取订阅信息进行处理
config_load "openclash"
config_foreach sub_info_get "config_subscribe"
config_foreach sub_info_get "config_subscribe" "$1"
uci -q delete openclash.config.config_update_path
uci commit openclash

View File

@ -3,13 +3,16 @@
. /usr/share/openclash/openclash_ps.sh
. /usr/share/openclash/log.sh
github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0)
if [ "$github_address_mod" = "0" ] && [ "$1" != "one_key_update" ] && [ "$2" != "one_key_update" ]; then
LOG_OUT "Tip: If the download fails, try setting the CDN in Overwrite Settings - General Settings - Github Address Modify Options"
fi
CORE_TYPE="$1"
C_CORE_TYPE=$(uci -q get openclash.config.core_type)
[ -z "$CORE_TYPE" ] || [ "$1" = "one_key_update" ] && CORE_TYPE="Dev"
small_flash_memory=$(uci -q get openclash.config.small_flash_memory)
CPU_MODEL=$(uci -q get openclash.config.core_version)
RELEASE_BRANCH=$(uci -q get openclash.config.release_branch || echo "master")
github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0)
LOG_FILE="/tmp/openclash.log"
[ ! -f "/tmp/clash_last_version" ] && /usr/share/openclash/clash_version.sh 2>/dev/null

View File

@ -49,11 +49,15 @@ lan_ip=$(uci -q get network.lan.ipaddr |awk -F '/' '{print $1}' 2>/dev/null || i
dnsmasq_default_resolvfile=$(uci -q get openclash.config.default_resolvfile)
if [ -z "$RAW_CONFIG_FILE" ] || [ ! -f "$RAW_CONFIG_FILE" ]; then
CONFIG_NAME=$(ls -lt /etc/openclash/config/ | grep -E '.yaml|.yml' | head -n 1 |awk '{print $9}')
if [ ! -z "$CONFIG_NAME" ]; then
RAW_CONFIG_FILE="/etc/openclash/config/$CONFIG_NAME"
CONFIG_FILE="/etc/openclash/$CONFIG_NAME"
fi
for file_name in /etc/openclash/config/*
do
if [ -f "$file_name" ]; then
RAW_CONFIG_FILE=$file_name
CONFIG_NAME=$(echo "$RAW_CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
CONFIG_FILE="/etc/openclash/$CONFIG_NAME"
break
fi
done
fi
ts_cf()

View File

@ -152,8 +152,14 @@
ifrestart=0
if [ -z "$CONFIG_FILE" ]; then
CONFIG_FILE="/etc/openclash/config/$(ls -lt /etc/openclash/config/ | grep -E '.yaml|.yml' | head -n 1 |awk '{print $9}')"
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
for file_name in /etc/openclash/config/*
do
if [ -f "$file_name" ]; then
CONFIG_FILE=$file_name
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
break
fi
done
fi
if [ -z "$CONFIG_NAME" ]; then

View File

@ -115,8 +115,8 @@ function unlock_auto_select()
key_group = UCI:get("openclash", "config", "stream_auto_select_group_key_bilibili") or "bilibili"
elseif type == "Google" then
key_group = UCI:get("openclash", "config", "stream_auto_select_group_key_google_not_cn") or "google|谷歌"
elseif type == "ChatGPT" then
key_group = UCI:get("openclash", "config", "stream_auto_select_group_key_chatgpt") or "ChatGPT"
elseif type == "OpenAI" then
key_group = UCI:get("openclash", "config", "stream_auto_select_group_key_openai") or "OpenAI|ChatGPT"
end
if not key_group then key_group = type end
else
@ -715,8 +715,8 @@ function nodes_filter(t, info)
regex = UCI:get("openclash", "config", "stream_auto_select_node_key_bilibili") or ""
elseif type == "Google" then
regex = UCI:get("openclash", "config", "stream_auto_select_node_key_google_not_cn") or ""
elseif type == "ChatGPT" then
regex = UCI:get("openclash", "config", "stream_auto_select_node_key_chatgpt") or ""
elseif type == "OpenAI" then
regex = UCI:get("openclash", "config", "stream_auto_select_node_key_openai") or ""
end
if class_type(t) == "table" then
@ -779,8 +779,8 @@ function proxy_unlock_test()
region, old_region = bilibili_unlock_test()
elseif type == "Google" then
region, old_region = google_not_cn_test()
elseif type == "ChatGPT" then
region, old_region = chatgpt_unlock_test()
elseif type == "OpenAI" then
region, old_region = openai_unlock_test()
end
return region, old_region
end
@ -814,7 +814,7 @@ function auto_get_policy_group(passwd, ip, port)
SYS.call('curl -sL -m 5 --limit-rate 1k -o /dev/null https://www.bilibili.com/ &')
elseif type == "Google" then
SYS.call('curl -sL -m 5 --limit-rate 1k -o /dev/null https://timeline.google.com &')
elseif type == "ChatGPT" then
elseif type == "OpenAI" then
SYS.call('curl -sL -m 5 --limit-rate 1k -o /dev/null https://chat.openai.com/ &')
end
os.execute("sleep 1")
@ -889,7 +889,7 @@ function auto_get_policy_group(passwd, ip, port)
auto_get_group = con.connections[i].chains[#(con.connections[i].chains)]
break
end
elseif type == "ChatGPT" then
elseif type == "OpenAI" then
if string.match(con.connections[i].metadata.host, "chat%.openai%.com") then
auto_get_group = con.connections[i].chains[#(con.connections[i].chains)]
break
@ -1496,11 +1496,11 @@ function google_not_cn_test()
end
end
function chatgpt_unlock_test()
function openai_unlock_test()
status = 0
local url = "https://chat.openai.com/"
local region_url = "https://chat.openai.com/cdn-cgi/trace"
local regex = UCI:get("openclash", "config", "stream_auto_select_region_key_chatgpt") or ""
local regex = UCI:get("openclash", "config", "stream_auto_select_region_key_openai") or ""
local region = ""
local old_region = ""
local data = SYS.exec(string.format("curl -sIL --connect-timeout 5 -m 5 --speed-time 5 --speed-limit 1 --retry 2 -H 'Accept-Language: en' -H 'Content-Type: application/json' -H 'User-Agent: %s' '%s'", UA, url))

View File

@ -11,14 +11,11 @@ del_lock() {
rm -rf "/tmp/lock/openclash_update.lock"
}
#一键更新
if [ "$1" = "one_key_update" ]; then
uci -q set openclash.config.enable=1
uci -q commit openclash
/usr/share/openclash/openclash_core.sh "$1" >/dev/null 2>&1 &
/usr/share/openclash/openclash_core.sh "TUN" "$1" >/dev/null 2>&1 &
/usr/share/openclash/openclash_core.sh "Meta" "$1" >/dev/null 2>&1 &
wait
[ ! -f "/tmp/openclash_last_version" ] && /usr/share/openclash/openclash_version.sh 2>/dev/null
if [ ! -f "/tmp/openclash_last_version" ]; then
LOG_OUT "Error: Failed to Get Version Information, Please Try Again Later..."
SLOG_CLEAN
exit 0
fi
LAST_OPVER="/tmp/openclash_last_version"
@ -26,8 +23,26 @@ LAST_VER=$(sed -n 1p "$LAST_OPVER" 2>/dev/null |sed "s/^v//g" |tr -d "\n")
OP_CV=$(rm -f /var/lock/opkg.lock && opkg status luci-app-openclash 2>/dev/null |grep 'Version' |awk -F '-' '{print $1}' |awk -F 'Version: ' '{print $2}' |awk -F '.' '{print $2$3}' 2>/dev/null)
OP_LV=$(sed -n 1p "$LAST_OPVER" 2>/dev/null |awk -F '-' '{print $1}' |awk -F 'v' '{print $2}' |awk -F '.' '{print $2$3}' 2>/dev/null)
RELEASE_BRANCH=$(uci -q get openclash.config.release_branch || echo "master")
github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0)
LOG_FILE="/tmp/openclash.log"
github_address_mod=$(uci -q get openclash.config.github_address_mod || echo 0)
#一键更新
if [ "$1" = "one_key_update" ]; then
uci -q set openclash.config.enable=1
uci -q commit openclash
if [ "$github_address_mod" = "0" ]; then
LOG_OUT "Tip: If the download fails, try setting the CDN in Overwrite Settings - General Settings - Github Address Modify Options"
fi
/usr/share/openclash/openclash_core.sh "$1" >/dev/null 2>&1 &
/usr/share/openclash/openclash_core.sh "TUN" "$1" >/dev/null 2>&1 &
/usr/share/openclash/openclash_core.sh "Meta" "$1" >/dev/null 2>&1 &
wait
else
if [ "$github_address_mod" = "0" ]; then
LOG_OUT "Tip: If the download fails, try setting the CDN in Overwrite Settings - General Settings - Github Address Modify Options"
fi
fi
set_lock
if [ -n "$OP_CV" ] && [ -n "$OP_LV" ] && [ "$(expr "$OP_LV" \> "$OP_CV")" -eq 1 ] && [ -f "$LAST_OPVER" ]; then
@ -114,7 +129,7 @@ EOF
fi
else
if [ ! -f "$LAST_OPVER" ] || [ -z "$OP_CV" ] || [ -z "$OP_LV" ]; then
LOG_OUT "Failed to Get Version Information, Please Try Again Later..."
LOG_OUT "Error: Failed to Get Version Information, Please Try Again Later..."
else
LOG_OUT "OpenClash Has not Been Updated, Stop Continuing!"
fi

View File

@ -1,4 +1,5 @@
#!/bin/bash
TIME=$(date "+%Y-%m-%d-%H")
CHTIME=$(date "+%Y-%m-%d-%H" -r "/tmp/openclash_last_version" 2>/dev/null)
LAST_OPVER="/tmp/openclash_last_version"

View File

@ -110,7 +110,7 @@ do
stream_auto_select_discovery_plus=$(uci -q get openclash.config.stream_auto_select_discovery_plus || echo 0)
stream_auto_select_bilibili=$(uci -q get openclash.config.stream_auto_select_bilibili || echo 0)
stream_auto_select_google_not_cn=$(uci -q get openclash.config.stream_auto_select_google_not_cn || echo 0)
stream_auto_select_chatgpt=$(uci -q get openclash.config.stream_auto_select_chatgpt || echo 0)
stream_auto_select_openai=$(uci -q get openclash.config.stream_auto_select_openai || echo 0)
upnp_lease_file=$(uci -q get upnpd.config.upnp_lease_file)
enable=$(uci -q get openclash.config.enable)
@ -142,7 +142,7 @@ if [ "$enable" -eq 1 ]; then
if [ "$core_type" == "TUN" ] || [ "$core_type" == "Meta" ]; then
ip route replace default dev utun table "$PROXY_ROUTE_TABLE" 2>/dev/null
ip rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" 2>/dev/null
if [ "$ipv6_mode" -eq 2 ] && [ "$ipv6_enable" -eq 1 ]; then
if [ "$ipv6_mode" -eq 2 ] && [ "$ipv6_enable" -eq 1 ] && [ "$core_type" == "Meta" ]; then
ip -6 rule del oif utun table 2022 >/dev/null 2>&1
ip -6 route del default dev utun table 2022 >/dev/null 2>&1
ip -6 route replace default dev utun table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
@ -355,9 +355,9 @@ fi
LOG_OUT "Tip: Start Auto Select Proxy For Bilibili Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "Bilibili" >> $LOG_FILE
fi
if [ "$stream_auto_select_chatgpt" -eq 1 ]; then
LOG_OUT "Tip: Start Auto Select Proxy For ChatGPT Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "ChatGPT" >> $LOG_FILE
if [ "$stream_auto_select_openai" -eq 1 ]; then
LOG_OUT "Tip: Start Auto Select Proxy For OpenAI Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "OpenAI" >> $LOG_FILE
fi
fi
fi

View File

@ -164,3 +164,4 @@ Steam-社区,Steam.rules
魔兽世界-欧服,WoW-EU.rules
游戏王决斗链接,YO-GI-HO delulinks.rules
游侠对战平台,YouXiaDuiZhanPingTai.rules
YY语音平台,YY-cn.rules

View File

@ -1,515 +1,524 @@
rules:
- RULE-SET,Reject,AdBlock
- RULE-SET,Special,DIRECT
- RULE-SET,Netflix,Netflix
- RULE-SET,Disney Plus,Disney
- RULE-SET,YouTube,YouTube
- RULE-SET,Spotify,Spotify
- RULE-SET,Bilibili,Asian TV
- RULE-SET,IQ,Asian TV
- RULE-SET,IQIYI,Asian TV
- RULE-SET,Letv,Asian TV
- RULE-SET,Netease Music,Asian TV
- RULE-SET,Tencent Video,Asian TV
- RULE-SET,Youku,Asian TV
- RULE-SET,WeTV,Asian TV
- RULE-SET,ABC,Global TV
- RULE-SET,Abema TV,Global TV
- RULE-SET,Amazon,Global TV
- RULE-SET,Bahamut,Global TV
- RULE-SET,BBC iPlayer,Global TV
- RULE-SET,DAZN,Global TV
- RULE-SET,Discovery Plus,Global TV
- RULE-SET,encoreTVB,Global TV
- RULE-SET,F1 TV,Global TV
- RULE-SET,Fox Now,Global TV
- RULE-SET,Fox+,Global TV
- RULE-SET,HBO Go,Global TV
- RULE-SET,HBO Max,Global TV
- RULE-SET,Hulu Japan,Global TV
- RULE-SET,Hulu,Global TV
- RULE-SET,Japonx,Global TV
- RULE-SET,JOOX,Global TV
- RULE-SET,KKBOX,Global TV
- RULE-SET,KKTV,Global TV
- RULE-SET,Line TV,Global TV
- RULE-SET,myTV SUPER,Global TV
- RULE-SET,Niconico,Global TV
- RULE-SET,Pandora,Global TV
- RULE-SET,PBS,Global TV
- RULE-SET,Pornhub,Global TV
- RULE-SET,Soundcloud,Global TV
- RULE-SET,ViuTV,Global TV
- RULE-SET,Apple Music,Apple TV
- RULE-SET,Apple News,Apple TV
- RULE-SET,Apple TV,Apple TV
- RULE-SET,Apple,Apple
- RULE-SET,Telegram,Telegram
- RULE-SET,ChatGPT,ChatGPT
- RULE-SET,Crypto,Crypto
- RULE-SET,Discord,Discord
- RULE-SET,Google FCM,Google FCM
- RULE-SET,Microsoft,Microsoft
- RULE-SET,PayPal,PayPal
- RULE-SET,Scholar,Scholar
- RULE-SET,Speedtest,Speedtest
- RULE-SET,Steam,Steam
- RULE-SET,miHoYo,miHoYo
- RULE-SET,PROXY,Proxy
- RULE-SET,Domestic,Domestic
- RULE-SET,Domestic IPs,Domestic
- RULE-SET,LAN,DIRECT
- GEOIP,CN,Domestic
- MATCH,Others
- RULE-SET, Reject, AdBlock
- RULE-SET, Special, DIRECT
- RULE-SET, Anti IP, Anti IP
- RULE-SET, Netflix, Netflix
- RULE-SET, Disney Plus, Disney
- RULE-SET, YouTube, YouTube
- RULE-SET, Spotify, Spotify
- RULE-SET, Bilibili, Asian TV
- RULE-SET, IQ, Asian TV
- RULE-SET, IQIYI, Asian TV
- RULE-SET, Letv, Asian TV
- RULE-SET, Netease Music, Asian TV
- RULE-SET, Tencent Video, Asian TV
- RULE-SET, Youku, Asian TV
- RULE-SET, WeTV, Asian TV
- RULE-SET, ABC, Global TV
- RULE-SET, Abema TV, Global TV
- RULE-SET, Amazon, Global TV
- RULE-SET, Bahamut, Global TV
- RULE-SET, BBC iPlayer, Global TV
- RULE-SET, DAZN, Global TV
- RULE-SET, Discovery Plus, Global TV
- RULE-SET, encoreTVB, Global TV
- RULE-SET, F1 TV, Global TV
- RULE-SET, Fox Now, Global TV
- RULE-SET, Fox+, Global TV
- RULE-SET, HBO Go, Global TV
- RULE-SET, HBO Max, Global TV
- RULE-SET, Hulu Japan, Global TV
- RULE-SET, Hulu, Global TV
- RULE-SET, Japonx, Global TV
- RULE-SET, JOOX, Global TV
- RULE-SET, KKBOX, Global TV
- RULE-SET, KKTV, Global TV
- RULE-SET, Line TV, Global TV
- RULE-SET, myTV SUPER, Global TV
- RULE-SET, Niconico, Global TV
- RULE-SET, Pandora, Global TV
- RULE-SET, PBS, Global TV
- RULE-SET, Pornhub, Global TV
- RULE-SET, Soundcloud, Global TV
- RULE-SET, ViuTV, Global TV
- RULE-SET, Apple Music, Apple TV
- RULE-SET, Apple News, Apple TV
- RULE-SET, Apple TV, Apple TV
- RULE-SET, Apple, Apple
- RULE-SET, Telegram, Telegram
- RULE-SET, Crypto, Crypto
- RULE-SET, Discord, Discord
- RULE-SET, Google FCM, Google FCM
- RULE-SET, Microsoft, Microsoft
- RULE-SET, OpenAI, OpenAI
- RULE-SET, PayPal, PayPal
- RULE-SET, Scholar, Scholar
- RULE-SET, Speedtest, Speedtest
- RULE-SET, Steam, Steam
- RULE-SET, miHoYo, miHoYo
- RULE-SET, PROXY, Proxy
- RULE-SET, Domestic, Domestic
- RULE-SET, Domestic IPs, Domestic
- RULE-SET, LAN, DIRECT
- GEOIP, CN, Domestic
- MATCH, Others
script:
code: |
def main(ctx, metadata):
ruleset_action = {"Reject": "AdBlock",
"Special": "DIRECT",
"Netflix": "Netflix",
"Disney Plus": "Disney",
"YouTube": "YouTube",
"Spotify": "Spotify",
"Bilibili": "Asian TV",
"IQ": "Asian TV",
"IQIYI": "Asian TV",
"Letv": "Asian TV",
"Netease Music": "Asian TV",
"Tencent Video": "Asian TV",
"Youku": "Asian TV",
"WeTV": "Asian TV",
"ABC": "Global TV",
"Abema TV": "Global TV",
"Amazon": "Global TV",
"Bahamut": "Global TV",
"BBC iPlayer": "Global TV",
"DAZN": "Global TV",
"Discovery Plus": "Global TV",
"encoreTVB": "Global TV",
"F1 TV": "Global TV",
"Fox Now": "Global TV",
"Fox+": "Global TV",
"HBO Go": "Global TV",
"HBO Max": "Global TV",
"Hulu Japan": "Global TV",
"Hulu": "Global TV",
"Japonx": "Global TV",
"JOOX": "Global TV",
"KKBOX": "Global TV",
"KKTV": "Global TV",
"Line TV": "Global TV",
"myTV SUPER": "Global TV",
"Niconico": "Global TV",
"Pandora": "Global TV",
"PBS": "Global TV",
"Pornhub": "Global TV",
"Soundcloud": "Global TV",
"ViuTV": "Global TV",
"Apple Music": "Apple TV",
"Apple News": "Apple TV",
"Apple TV": "Apple TV",
"Apple": "Apple",
"Telegram": "Telegram",
"ChatGPT": "ChatGPT",
"Crypto": "Crypto",
"Discord": "Discord",
"Google FCM": "Google FCM",
"Microsoft": "Microsoft",
"PayPal": "PayPal",
"Scholar": "Scholar",
"Speedtest": "Speedtest",
"Steam": "Steam",
"miHoYo": "miHoYo",
"PROXY": "Proxy",
"Domestic": "Domestic",
"Domestic IPs": "Domestic",
"LAN": "DIRECT"
ruleset_action = {
'Reject': 'AdBlock',
'Special': 'DIRECT',
'Anti IP': 'Anti IP',
'Netflix': 'Netflix',
'Disney Plus': 'Disney',
'YouTube': 'YouTube',
'Spotify': 'Spotify',
'Bilibili': 'Asian TV',
'IQ': 'Asian TV',
'IQIYI': 'Asian TV',
'Letv': 'Asian TV',
'Netease Music': 'Asian TV',
'Tencent Video': 'Asian TV',
'Youku': 'Asian TV',
'WeTV': 'Asian TV',
'ABC': 'Global TV',
'Abema TV': 'Global TV',
'Amazon': 'Global TV',
'Bahamut': 'Global TV',
'BBC iPlayer': 'Global TV',
'DAZN': 'Global TV',
'Discovery Plus': 'Global TV',
'encoreTVB': 'Global TV',
'F1 TV': 'Global TV',
'Fox Now': 'Global TV',
'Fox+': 'Global TV',
'HBO Go': 'Global TV',
'HBO Max': 'Global TV',
'Hulu Japan': 'Global TV',
'Hulu': 'Global TV',
'Japonx': 'Global TV',
'JOOX': 'Global TV',
'KKBOX': 'Global TV',
'KKTV': 'Global TV',
'Line TV': 'Global TV',
'myTV SUPER': 'Global TV',
'Niconico': 'Global TV',
'Pandora': 'Global TV',
'PBS': 'Global TV',
'Pornhub': 'Global TV',
'Soundcloud': 'Global TV',
'ViuTV': 'Global TV',
'Apple Music': 'Apple TV',
'Apple News': 'Apple TV',
'Apple TV': 'Apple TV',
'Apple': 'Apple',
'Telegram': 'Telegram',
'Crypto': 'Crypto',
'Discord': 'Discord',
'Google FCM': 'Google FCM',
'Microsoft': 'Microsoft',
'OpenAI': 'OpenAI',
'PayPal': 'PayPal',
'Scholar': 'Scholar',
'Speedtest': 'Speedtest',
'Steam': 'Steam',
'miHoYo': 'miHoYo',
'PROXY': 'Proxy',
'Domestic': 'Domestic',
'Domestic IPs': 'Domestic',
'LAN': 'DIRECT'
}
port = int(metadata["dst_port"])
port = int(metadata['dst_port'])
if metadata["network"] == "UDP" and port == 443:
if metadata['network'] == 'UDP' and port == 443:
ctx.log('[Script] matched QUIC traffic use reject')
return "REJECT"
return 'REJECT'
port_list = [21, 22, 23, 53, 80, 123, 143, 194, 443, 465, 587, 853, 993, 995, 998, 2052, 2053, 2082, 2083, 2086, 2095, 2096, 3389, 5222, 5228, 5229, 5230, 8080, 8443, 8880, 8888, 8889]
if port not in port_list:
ctx.log('[Script] not common port use direct')
return "DIRECT"
return 'DIRECT'
if metadata["dst_ip"] == "":
metadata["dst_ip"] = ctx.resolve_ip(metadata["host"])
if metadata['dst_ip'] == '':
metadata['dst_ip'] = ctx.resolve_ip(metadata['host'])
for ruleset in ruleset_action:
if ctx.rule_providers[ruleset].match(metadata):
return ruleset_action[ruleset]
if metadata["dst_ip"] != "":
code = ctx.geoip(metadata["dst_ip"])
if code == "CN":
if metadata['dst_ip'] != '':
code = ctx.geoip(metadata['dst_ip'])
if code == 'CN':
ctx.log('[Script] Geoip CN')
return "Domestic"
return 'Domestic'
ctx.log('[Script] FINAL')
return "Others"
return 'Others'
rule-providers:
Reject:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Reject.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Reject.yaml
path: "./Rules/Reject"
interval: 86400
Special:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Special.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Special.yaml
path: "./Rules/Special"
interval: 86400
PROXY:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Proxy.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Proxy.yaml
path: "./Rules/Proxy"
interval: 86400
Domestic:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Domestic.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Domestic.yaml
path: "./Rules/Domestic"
interval: 86400
Domestic IPs:
type: http
behavior: ipcidr
url: https://dler.cloud/Rules/Clash/Provider/Domestic%20IPs.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Domestic%20IPs.yaml
path: "./Rules/Domestic_IPs"
interval: 86400
LAN:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/LAN.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/LAN.yaml
path: "./Rules/LAN"
interval: 86400
Anti IP:
type: http
behavior: classical
url: https://raw.githubusercontent.com/lwd-temp/anti-ip-attribution/main/generated/rule-provider.yaml
path: "./Rules/Anti_IP"
interval: 86400
Netflix:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Netflix.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Netflix.yaml
path: "./Rules/Media/Netflix"
interval: 86400
Spotify:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Spotify.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Spotify.yaml
path: "./Rules/Media/Spotify"
interval: 86400
YouTube:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/YouTube.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/YouTube.yaml
path: "./Rules/Media/YouTube"
interval: 86400
Bilibili:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Bilibili.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Bilibili.yaml
path: "./Rules/Media/Bilibili"
interval: 86400
IQ:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/IQ.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/IQ.yaml
path: "./Rules/Media/IQI"
interval: 86400
IQIYI:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/IQIYI.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/IQIYI.yaml
path: "./Rules/Media/IQYI"
interval: 86400
Letv:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Letv.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Letv.yaml
path: "./Rules/Media/Letv"
interval: 86400
Netease Music:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Netease%20Music.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Netease%20Music.yaml
path: "./Rules/Media/Netease_Music"
interval: 86400
Tencent Video:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Tencent%20Video.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Tencent%20Video.yaml
path: "./Rules/Media/Tencent_Video"
interval: 86400
Youku:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Youku.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Youku.yaml
path: "./Rules/Media/Youku"
interval: 86400
WeTV:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/WeTV.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/WeTV.yaml
path: "./Rules/Media/WeTV"
interval: 86400
ABC:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/ABC.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/ABC.yaml
path: "./Rules/Media/ABC"
interval: 86400
Abema TV:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Abema%20TV.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Abema%20TV.yaml
path: "./Rules/Media/Abema_TV"
interval: 86400
Amazon:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Amazon.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Amazon.yaml
path: "./Rules/Media/Amazon"
interval: 86400
Apple Music:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Apple%20Music.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Apple%20Music.yaml
path: "./Rules/Media/Apple_Music"
interval: 86400
Apple News:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Apple%20News.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Apple%20News.yaml
path: "./Rules/Media/Apple_News"
interval: 86400
Apple TV:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Apple%20TV.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Apple%20TV.yaml
path: "./Rules/Media/Apple_TV"
interval: 86400
Bahamut:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Bahamut.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Bahamut.yaml
path: "./Rules/Media/Bahamut"
interval: 86400
BBC iPlayer:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/BBC%20iPlayer.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/BBC%20iPlayer.yaml
path: "./Rules/Media/BBC_iPlayer"
interval: 86400
DAZN:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/DAZN.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/DAZN.yaml
path: "./Rules/Media/DAZN"
interval: 86400
Discovery Plus:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Discovery%20Plus.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Discovery%20Plus.yaml
path: "./Rules/Media/Discovery_Plus"
interval: 86400
Disney Plus:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Disney%20Plus.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Disney%20Plus.yaml
path: "./Rules/Media/Disney_Plus"
interval: 86400
encoreTVB:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/encoreTVB.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/encoreTVB.yaml
path: "./Rules/Media/encoreTVB"
interval: 86400
F1 TV:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/F1%20TV.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/F1%20TV.yaml
path: "./Rules/Media/F1_TV"
interval: 86400
Fox Now:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Fox%20Now.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Fox%20Now.yaml
path: "./Rules/Media/Fox_Now"
interval: 86400
Fox+:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Fox%2B.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Fox%2B.yaml
path: "./Rules/Media/Fox+"
interval: 86400
HBO Go:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/HBO%20Go.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/HBO%20Go.yaml
path: "./Rules/Media/HBO_Go"
interval: 86400
HBO Max:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/HBO%20Max.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/HBO%20Max.yaml
path: "./Rules/Media/HBO_Max"
interval: 86400
Hulu Japan:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Hulu%20Japan.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Hulu%20Japan.yaml
path: "./Rules/Media/Hulu_Japan"
interval: 86400
Hulu:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Hulu.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Hulu.yaml
path: "./Rules/Media/Hulu"
interval: 86400
Japonx:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Japonx.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Japonx.yaml
path: "./Rules/Media/Japonx"
interval: 86400
JOOX:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/JOOX.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/JOOX.yaml
path: "./Rules/Media/JOOX"
interval: 86400
KKBOX:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/KKBOX.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/KKBOX.yaml
path: "./Rules/Media/KKBOX"
interval: 86400
KKTV:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/KKTV.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/KKTV.yaml
path: "./Rules/Media/KKTV"
interval: 86400
Line TV:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Line%20TV.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Line%20TV.yaml
path: "./Rules/Media/Line_TV"
interval: 86400
myTV SUPER:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/myTV%20SUPER.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/myTV%20SUPER.yaml
path: "./Rules/Media/myTV_SUPER"
interval: 86400
Niconico:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Niconico.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Niconico.yaml
path: "./Rules/Media/Niconico"
interval: 86400
Pandora:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Pandora.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Pandora.yaml
path: "./Rules/Media/Pandora"
interval: 86400
PBS:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/PBS.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/PBS.yaml
path: "./Rules/Media/PBS"
interval: 86400
Pornhub:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Pornhub.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Pornhub.yaml
path: "./Rules/Media/Pornhub"
interval: 86400
Soundcloud:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/Soundcloud.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/Soundcloud.yaml
path: "./Rules/Media/Soundcloud"
interval: 86400
ViuTV:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Media/ViuTV.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Media/ViuTV.yaml
path: "./Rules/Media/ViuTV"
interval: 86400
Telegram:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Telegram.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Telegram.yaml
path: "./Rules/Telegram"
interval: 86400
Crypto:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Crypto.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Crypto.yaml
path: "./Rules/Crypto"
interval: 86400
Discord:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Discord.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Discord.yaml
path: "./Rules/Discord"
interval: 86400
Steam:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Steam.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Steam.yaml
path: "./Rules/Steam"
interval: 86400
Speedtest:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Speedtest.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Speedtest.yaml
path: "./Rules/Speedtest"
interval: 86400
PayPal:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/PayPal.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/PayPal.yaml
path: "./Rules/PayPal"
interval: 86400
Microsoft:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Microsoft.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Microsoft.yaml
path: "./Rules/Microsoft"
interval: 86400
ChatGPT:
OpenAI:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/ChatGPT.yaml
path: "./Rules/ChatGPT"
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/OpenAI.yaml
path: "./Rules/OpenAI"
interval: 86400
Apple:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Apple.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Apple.yaml
path: "./Rules/Apple"
interval: 86400
Google FCM:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Google%20FCM.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Google%20FCM.yaml
path: "./Rules/Google FCM"
interval: 86400
Scholar:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/Scholar.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/Scholar.yaml
path: "./Rules/Scholar"
interval: 86400
miHoYo:
type: http
behavior: classical
url: https://dler.cloud/Rules/Clash/Provider/miHoYo.yaml
url: https://raw.githubusercontent.com/dler-io/Rules/main/Clash/Provider/miHoYo.yaml
path: "./Rules/miHoYo"
interval: 86400

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8,9 +8,9 @@
<meta name="description" content="Clash web port" />
<!--meta name="external-controller" content="http://secret@example.com:9090"-->
<title>Clash</title>
<script type="module" crossorigin src="./assets/index-a1967476.js"></script>
<link rel="modulepreload" crossorigin href="./assets/vendor-0606363c.js">
<link rel="stylesheet" href="./assets/index-9ebfe719.css">
<script type="module" crossorigin src="./assets/index-abc6db04.js"></script>
<link rel="modulepreload" crossorigin href="./assets/vendor-0c169955.js">
<link rel="stylesheet" href="./assets/index-41a41303.css">
<link rel="manifest" href="./manifest.webmanifest"><script id="vite-plugin-pwa:inline-sw">if('serviceWorker' in navigator) {window.addEventListener('load', () => {navigator.serviceWorker.register('./sw.js', { scope: './' })})}</script></head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

View File

@ -1 +1 @@
if(!self.define){let e,s={};const n=(n,i)=>(n=new URL(n+".js",i).href,s[n]||new Promise((s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()})).then((()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didnt register its module`);return e})));self.define=(i,t)=>{const r=e||("document"in self?document.currentScript.src:"")||location.href;if(s[r])return;let o={};const l=e=>n(e,r),d={module:{uri:r},exports:o,require:l};s[r]=Promise.all(i.map((e=>d[e]||l(e)))).then((e=>(t(...e),o)))}}define(["./workbox-e0782b83"],(function(e){"use strict";self.addEventListener("message",(e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()})),e.precacheAndRoute([{url:"assets/index-9ebfe719.css",revision:null},{url:"assets/index-a1967476.js",revision:null},{url:"assets/vendor-0606363c.js",revision:null},{url:"index.html",revision:"ac6496dc8e5aad8b0ae34cda277c7b21"},{url:"manifest.webmanifest",revision:"d3dd1da0aa7614180924343e65244285"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))}));
if(!self.define){let e,s={};const n=(n,i)=>(n=new URL(n+".js",i).href,s[n]||new Promise((s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()})).then((()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didnt register its module`);return e})));self.define=(i,t)=>{const r=e||("document"in self?document.currentScript.src:"")||location.href;if(s[r])return;let o={};const l=e=>n(e,r),d={module:{uri:r},exports:o,require:l};s[r]=Promise.all(i.map((e=>d[e]||l(e)))).then((e=>(t(...e),o)))}}define(["./workbox-4de3aa5f"],(function(e){"use strict";self.addEventListener("message",(e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()})),e.precacheAndRoute([{url:"assets/index-41a41303.css",revision:null},{url:"assets/index-abc6db04.js",revision:null},{url:"assets/vendor-0c169955.js",revision:null},{url:"index.html",revision:"9a8a6ecd862a646bcb1c971fed6d9e82"},{url:"manifest.webmanifest",revision:"d3dd1da0aa7614180924343e65244285"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))}));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
import{j as e,b,i as y,r as l}from"./index-3e6aad90.js";const E="_spining_4i8sg_1",F="_spining_keyframes_4i8sg_1",M={spining:E,spining_keyframes:F},{useState:j}=y;function B({children:s}){return e("span",{className:M.spining,children:s})}const H={right:10,bottom:10},L=({children:s,...n})=>e("button",{type:"button",...n,className:"rtf--ab",children:s}),v=({children:s,...n})=>e("button",{type:"button",className:"rtf--mb",...n,children:s}),O={bottom:24,right:24},R=({event:s="hover",style:n=O,alwaysShowTitle:o=!1,children:f,icon:g,mainButtonStyles:h,onClick:p,text:d,..._})=>{const[a,r]=j(!1),c=o||!a,u=()=>r(!0),m=()=>r(!1),k=()=>s==="hover"&&u(),x=()=>s==="hover"&&m(),N=t=>p?p(t):(t.persist(),s==="click"?a?m():u():null),$=(t,i)=>{t.persist(),r(!1),setTimeout(()=>{i(t)},1)},C=()=>l.Children.map(f,(t,i)=>l.isValidElement(t)?b("li",{className:`rtf--ab__c ${"top"in n?"top":""}`,children:[l.cloneElement(t,{"data-testid":`action-button-${i}`,"aria-label":t.props.text||`Menu button ${i+1}`,"aria-hidden":c,tabIndex:a?0:-1,...t.props,onClick:I=>{t.props.onClick&&$(I,t.props.onClick)}}),t.props.text&&e("span",{className:`${"right"in n?"right":""} ${o?"always-show":""}`,"aria-hidden":c,children:t.props.text})]}):null);return e("ul",{onMouseEnter:k,onMouseLeave:x,className:`rtf ${a?"open":"closed"}`,"data-testid":"fab",style:n,..._,children:b("li",{className:"rtf--mb__c",children:[e(v,{onClick:N,style:h,"data-testid":"main-button",role:"button","aria-label":"Floating menu",tabIndex:0,children:g}),d&&e("span",{className:`${"right"in n?"right":""} ${o?"always-show":""}`,"aria-hidden":c,children:d}),e("ul",{children:C()})]})})};export{L as A,R as F,B as I,H as p};

View File

@ -0,0 +1 @@
import{j as t,h as C,r as l}from"./index-aa3f8ed9.js";const E="_spining_4i8sg_1",I="_spining_keyframes_4i8sg_1",y={spining:E,spining_keyframes:I},{useState:F}=C;function A({children:n}){return t.jsx("span",{className:y.spining,children:n})}const B={right:10,bottom:10},R=({children:n,...e})=>t.jsx("button",{type:"button",...e,className:"rtf--ab",children:n}),M=({children:n,...e})=>t.jsx("button",{type:"button",className:"rtf--mb",...e,children:n}),v={bottom:24,right:24},H=({event:n="hover",style:e=v,alwaysShowTitle:o=!1,children:b,icon:f,mainButtonStyles:g,onClick:p,text:u,...x})=>{const[a,r]=F(!1),c=o||!a,d=()=>r(!0),m=()=>r(!1),h=()=>n==="hover"&&d(),_=()=>n==="hover"&&m(),j=s=>p?p(s):(s.persist(),n==="click"?a?m():d():null),k=(s,i)=>{s.persist(),r(!1),setTimeout(()=>{i(s)},1)},N=()=>l.Children.map(b,(s,i)=>l.isValidElement(s)?t.jsxs("li",{className:`rtf--ab__c ${"top"in e?"top":""}`,children:[l.cloneElement(s,{"data-testid":`action-button-${i}`,"aria-label":s.props.text||`Menu button ${i+1}`,"aria-hidden":c,tabIndex:a?0:-1,...s.props,onClick:$=>{s.props.onClick&&k($,s.props.onClick)}}),s.props.text&&t.jsx("span",{className:`${"right"in e?"right":""} ${o?"always-show":""}`,"aria-hidden":c,children:s.props.text})]}):null);return t.jsx("ul",{onMouseEnter:h,onMouseLeave:_,className:`rtf ${a?"open":"closed"}`,"data-testid":"fab",style:e,...x,children:t.jsxs("li",{className:"rtf--mb__c",children:[t.jsx(M,{onClick:j,style:g,"data-testid":"main-button",role:"button","aria-label":"Floating menu",tabIndex:0,children:f}),u&&t.jsx("span",{className:`${"right"in e?"right":""} ${o?"always-show":""}`,"aria-hidden":c,children:u}),t.jsx("ul",{children:N()})]})})};export{R as A,H as F,A as I,B as p};

View File

@ -1 +0,0 @@
import{r as m,R as f,k as d,j as n,b as g,e as b,J as P,K as R,y as L,L as N,u as w,C as z,S as C,N as W,O,h as j,P as k,i as I,c as E}from"./index-3e6aad90.js";import{a as $,F}from"./index.esm-37f2c08f.js";import{r as M,s as A,f as B}from"./logs-08774dd8.js";import{d as D}from"./debounce-c1ba2006.js";import{u as H}from"./useRemainingViewPortHeight-175c2a6c.js";import{F as K,p as q}from"./Fab-169bb281.js";import{P as J,a as V}from"./play-30aef65c.js";function v(){return v=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e},v.apply(this,arguments)}function Y(e,r){if(e==null)return{};var t=G(e,r),o,a;if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a<s.length;a++)o=s[a],!(r.indexOf(o)>=0)&&Object.prototype.propertyIsEnumerable.call(e,o)&&(t[o]=e[o])}return t}function G(e,r){if(e==null)return{};var t={},o=Object.keys(e),a,s;for(s=0;s<o.length;s++)a=o[s],!(r.indexOf(a)>=0)&&(t[a]=e[a]);return t}var x=m.forwardRef(function(e,r){var t=e.color,o=t===void 0?"currentColor":t,a=e.size,s=a===void 0?24:a,l=Y(e,["color","size"]);return f.createElement("svg",v({ref:r,xmlns:"http://www.w3.org/2000/svg",width:s,height:s,viewBox:"0 0 24 24",fill:"none",stroke:o,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},l),f.createElement("circle",{cx:"11",cy:"11",r:"8"}),f.createElement("line",{x1:"21",y1:"21",x2:"16.65",y2:"16.65"}))});x.propTypes={color:d.string,size:d.oneOfType([d.string,d.number])};x.displayName="Search";const Q=x,U="_RuleSearch_1oz2t_1",X="_RuleSearchContainer_1oz2t_5",Z="_inputWrapper_1oz2t_10",ee="_input_1oz2t_10",te="_iconWrapper_1oz2t_35",p={RuleSearch:U,RuleSearchContainer:X,inputWrapper:Z,input:ee,iconWrapper:te};function oe({dispatch:e,searchText:r,updateSearchText:t}){const[o,a]=m.useState(r),s=m.useCallback(i=>{e(t(i))},[e,t]),l=m.useMemo(()=>D(s,300),[s]),h=i=>{a(i.target.value),l(i.target.value)};return n("div",{className:p.RuleSearch,children:g("div",{className:p.RuleSearchContainer,children:[n("div",{className:p.inputWrapper,children:n("input",{type:"text",value:o,onChange:h,className:p.input})}),n("div",{className:p.iconWrapper,children:n(Q,{size:20})})]})})}const re=e=>({searchText:P(e),updateSearchText:R}),ae=b(re)(oe),ne="_logMeta_7a1x3_1",se="_logType_7a1x3_8",ce="_logTime_7a1x3_18",ie="_logText_7a1x3_24",le="_logsWrapper_7a1x3_37",pe="_logPlaceholder_7a1x3_51",ge="_logPlaceholderIcon_7a1x3_64",he="_search_7a1x3_68",c={logMeta:ne,logType:se,logTime:ce,logText:ie,logsWrapper:le,logPlaceholder:pe,logPlaceholderIcon:ge,search:he},{useCallback:S,memo:ue,useEffect:de}=I,_=30,me={debug:"#28792c",info:"var(--bg-log-info-tag)",warning:"#b99105",error:"#c11c1c"};function fe({time:e,even:r,payload:t,type:o}){const a=E({even:r},"log");return n("div",{className:a,children:g("div",{className:c.logMeta,children:[n("div",{className:c.logTime,children:e}),n("div",{className:c.logType,style:{backgroundColor:me[o]},children:o}),n("div",{className:c.logText,children:t})]})})}function _e(e,r){return r[e].id}const ve=ue(({index:e,style:r,data:t})=>{const o=t[e];return n("div",{style:r,children:n(fe,{...o})})},$);function xe({dispatch:e,logLevel:r,apiConfig:t,logs:o,logStreamingPaused:a}){const s=L(),l=S(()=>{a?M({...t,logLevel:r}):A(),s.app.updateAppConfig("logStreamingPaused",!a)},[t,r,a,s.app]),h=S(T=>e(N(T)),[e]);de(()=>{B({...t,logLevel:r},h)},[t,r,h]);const[i,y]=H(),{t:u}=w();return g("div",{children:[n(z,{title:u("Logs")}),n("div",{className:c.search,children:n(ae,{})}),n("div",{ref:i,style:{paddingBottom:_},children:o.length===0?g("div",{className:c.logPlaceholder,style:{height:y-_},children:[n("div",{className:c.logPlaceholderIcon,children:n(C,{width:200,height:200})}),n("div",{children:u("no_logs")})]}):g("div",{className:c.logsWrapper,children:[n(F,{height:y-_,width:"100%",itemCount:o.length,itemSize:80,itemData:o,itemKey:_e,children:ve}),n(K,{icon:a?n(J,{size:16}):n(V,{size:16}),mainButtonStyles:a?{background:"#e74c3c"}:{},style:q,text:u(a?"Resume Refresh":"Pause Refresh"),onClick:l})]})})]})}const ye=e=>({logs:W(e),logLevel:O(e),apiConfig:j(e),logStreamingPaused:k(e)}),we=b(ye)(xe);export{we as default};

View File

@ -0,0 +1 @@
import{r as d,R as x,P as u,j as t,d as y,A as R,D as T,w as P,E as w,u as L,C as N,S as z,F as C,G as W,g as O,H as k,h as I,c as E}from"./index-aa3f8ed9.js";import{a as F,F as M}from"./index.esm-9774ed4d.js";import{r as $,s as A,f as D}from"./logs-253cb530.js";import{d as H}from"./debounce-c1ba2006.js";import{u as B}from"./useRemainingViewPortHeight-8f8ae068.js";import{F as q,p as G}from"./Fab-82e79c68.js";import{P as K,a as V}from"./play-0c8e26e5.js";function f(){return f=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var o=arguments[r];for(var s in o)Object.prototype.hasOwnProperty.call(o,s)&&(e[s]=o[s])}return e},f.apply(this,arguments)}function Y(e,r){if(e==null)return{};var o=J(e,r),s,a;if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(a=0;a<n.length;a++)s=n[a],!(r.indexOf(s)>=0)&&Object.prototype.propertyIsEnumerable.call(e,s)&&(o[s]=e[s])}return o}function J(e,r){if(e==null)return{};var o={},s=Object.keys(e),a,n;for(n=0;n<s.length;n++)a=s[n],!(r.indexOf(a)>=0)&&(o[a]=e[a]);return o}var _=d.forwardRef(function(e,r){var o=e.color,s=o===void 0?"currentColor":o,a=e.size,n=a===void 0?24:a,l=Y(e,["color","size"]);return x.createElement("svg",f({ref:r,xmlns:"http://www.w3.org/2000/svg",width:n,height:n,viewBox:"0 0 24 24",fill:"none",stroke:s,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},l),x.createElement("circle",{cx:"11",cy:"11",r:"8"}),x.createElement("line",{x1:"21",y1:"21",x2:"16.65",y2:"16.65"}))});_.propTypes={color:u.string,size:u.oneOfType([u.string,u.number])};_.displayName="Search";const Q=_,U="_RuleSearch_1oz2t_1",X="_RuleSearchContainer_1oz2t_5",Z="_inputWrapper_1oz2t_10",ee="_input_1oz2t_10",te="_iconWrapper_1oz2t_35",p={RuleSearch:U,RuleSearchContainer:X,inputWrapper:Z,input:ee,iconWrapper:te};function oe({dispatch:e,searchText:r,updateSearchText:o}){const[s,a]=d.useState(r),n=d.useCallback(i=>{e(o(i))},[e,o]),l=d.useMemo(()=>H(n,300),[n]),g=i=>{a(i.target.value),l(i.target.value)};return t.jsx("div",{className:p.RuleSearch,children:t.jsxs("div",{className:p.RuleSearchContainer,children:[t.jsx("div",{className:p.inputWrapper,children:t.jsx("input",{type:"text",value:s,onChange:g,className:p.input})}),t.jsx("div",{className:p.iconWrapper,children:t.jsx(Q,{size:20})})]})})}const se=e=>({searchText:R(e),updateSearchText:T}),re=y(se)(oe),ae="_logMeta_7a1x3_1",ne="_logType_7a1x3_8",ce="_logTime_7a1x3_18",ie="_logText_7a1x3_24",le="_logsWrapper_7a1x3_37",pe="_logPlaceholder_7a1x3_51",ge="_logPlaceholderIcon_7a1x3_64",he="_search_7a1x3_68",c={logMeta:ae,logType:ne,logTime:ce,logText:ie,logsWrapper:le,logPlaceholder:pe,logPlaceholderIcon:ge,search:he},{useCallback:v,memo:ue,useEffect:de}=I,m=30,xe={debug:"#28792c",info:"var(--bg-log-info-tag)",warning:"#b99105",error:"#c11c1c"};function me({time:e,even:r,payload:o,type:s}){const a=E({even:r},"log");return t.jsx("div",{className:a,children:t.jsxs("div",{className:c.logMeta,children:[t.jsx("div",{className:c.logTime,children:e}),t.jsx("div",{className:c.logType,style:{backgroundColor:xe[s]},children:s}),t.jsx("div",{className:c.logText,children:o})]})})}function fe(e,r){return r[e].id}const S=ue(({index:e,style:r,data:o})=>{const s=o[e];return t.jsx("div",{style:r,children:t.jsx(me,{...s})})},F);S.displayName="MemoRow";function _e({dispatch:e,logLevel:r,apiConfig:o,logs:s,logStreamingPaused:a}){const n=P(),l=v(()=>{a?$({...o,logLevel:r}):A(),n.app.updateAppConfig("logStreamingPaused",!a)},[o,r,a,n.app]),g=v(b=>e(w(b)),[e]);de(()=>{D({...o,logLevel:r},g)},[o,r,g]);const[i,j]=B(),{t:h}=L();return t.jsxs("div",{children:[t.jsx(N,{title:h("Logs")}),t.jsx("div",{className:c.search,children:t.jsx(re,{})}),t.jsx("div",{ref:i,style:{paddingBottom:m},children:s.length===0?t.jsxs("div",{className:c.logPlaceholder,style:{height:j-m},children:[t.jsx("div",{className:c.logPlaceholderIcon,children:t.jsx(z,{width:200,height:200})}),t.jsx("div",{children:h("no_logs")})]}):t.jsxs("div",{className:c.logsWrapper,children:[t.jsx(M,{height:j-m,width:"100%",itemCount:s.length,itemSize:80,itemData:s,itemKey:fe,children:S}),t.jsx(q,{icon:a?t.jsx(K,{size:16}):t.jsx(V,{size:16}),mainButtonStyles:a?{background:"#e74c3c"}:{},style:G,text:h(a?"Resume Refresh":"Pause Refresh"),onClick:l})]})})]})}const je=e=>({logs:C(e),logLevel:W(e),apiConfig:O(e),logStreamingPaused:k(e)}),we=y(je)(_e);export{we as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
._select_13zm8_1{height:40px;line-height:1.5;width:100%;padding-left:8px;-webkit-appearance:none;appearance:none;background-color:var(--color-input-bg);color:var(--color-text);padding-right:20px;border-radius:4px;border:1px solid var(--color-input-border);background-image:url(data:image/svg+xml,%0A%20%20%20%20%3Csvg%20width%3D%228%22%20height%3D%2224%22%20viewBox%3D%220%200%208%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%20%20%3Cpath%20d%3D%22M4%207L7%2011H1L4%207Z%22%20fill%3D%22%23999999%22%20%2F%3E%0A%20%20%20%20%20%20%3Cpath%20d%3D%22M4%2017L1%2013L7%2013L4%2017Z%22%20fill%3D%22%23999999%22%20%2F%3E%0A%20%20%20%20%3C%2Fsvg%3E%0A%20%20);background-position:right 8px center;background-repeat:no-repeat}._select_13zm8_1:hover,._select_13zm8_1:focus{border-color:#343434;outline:none!important;color:var(--color-text-highlight);background-image:var(--select-bg-hover)}._select_13zm8_1:focus{box-shadow:#4299e199 0 0 0 3px}._select_13zm8_1 option{background-color:var(--color-background)}

View File

@ -0,0 +1 @@
._select_13zm8_1{height:40px;line-height:1.5;width:100%;padding-left:8px;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--color-input-bg);color:var(--color-text);padding-right:20px;border-radius:4px;border:1px solid var(--color-input-border);background-image:url(data:image/svg+xml,%0A%20%20%20%20%3Csvg%20width%3D%228%22%20height%3D%2224%22%20viewBox%3D%220%200%208%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%20%20%3Cpath%20d%3D%22M4%207L7%2011H1L4%207Z%22%20fill%3D%22%23999999%22%20%2F%3E%0A%20%20%20%20%20%20%3Cpath%20d%3D%22M4%2017L1%2013L7%2013L4%2017Z%22%20fill%3D%22%23999999%22%20%2F%3E%0A%20%20%20%20%3C%2Fsvg%3E%0A%20%20);background-position:right 8px center;background-repeat:no-repeat}._select_13zm8_1:hover,._select_13zm8_1:focus{border-color:#343434;outline:none!important;color:var(--color-text-highlight);background-image:var(--select-bg-hover)}._select_13zm8_1:focus{box-shadow:#4299e199 0 0 0 3px}._select_13zm8_1 option{background-color:var(--color-background)}

View File

@ -1 +0,0 @@
import{j as s}from"./index-3e6aad90.js";const o="_select_13zm8_1",r={select:o};function i({options:t,selected:c,onChange:l}){return s("select",{className:r.select,value:c,onChange:l,children:t.map(([e,n])=>s("option",{value:e,children:n},e))})}export{i as S};

View File

@ -0,0 +1 @@
import{j as s}from"./index-aa3f8ed9.js";const o="_select_13zm8_1",r={select:o};function m({options:t,selected:c,onChange:l}){return s.jsx("select",{className:r.select,value:c,onChange:l,children:t.map(([e,n])=>s.jsx("option",{value:e,children:n},e))})}export{m as S};

View File

@ -0,0 +1 @@
import{r as g,R as c,P as i,c as x,j as l,Q as d,h}from"./index-aa3f8ed9.js";import{d as m}from"./debounce-c1ba2006.js";function u(){return u=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var e=arguments[n];for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o])}return t},u.apply(this,arguments)}function v(t,n){if(t==null)return{};var e=_(t,n),o,r;if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(t);for(r=0;r<s.length;r++)o=s[r],!(n.indexOf(o)>=0)&&Object.prototype.propertyIsEnumerable.call(t,o)&&(e[o]=t[o])}return e}function _(t,n){if(t==null)return{};var e={},o=Object.keys(t),r,s;for(s=0;s<o.length;s++)r=o[s],!(n.indexOf(r)>=0)&&(e[r]=t[r]);return e}var p=g.forwardRef(function(t,n){var e=t.color,o=e===void 0?"currentColor":e,r=t.size,s=r===void 0?24:r,a=v(t,["color","size"]);return c.createElement("svg",u({ref:n,xmlns:"http://www.w3.org/2000/svg",width:s,height:s,viewBox:"0 0 24 24",fill:"none",stroke:o,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},a),c.createElement("polyline",{points:"23 4 23 10 17 10"}),c.createElement("path",{d:"M20.49 15a9 9 0 1 1-2.12-9.36L23 10"}))});p.propTypes={color:i.string,size:i.oneOfType([i.string,i.number])};p.displayName="RotateCw";const R=p,b="_rotate_1dspl_1",y="_isRotating_1dspl_5",j="_rotating_1dspl_1",f={rotate:b,isRotating:y,rotating:j};function $(t){const n=t.size||16,e=x(f.rotate,{[f.isRotating]:t.isRotating});return l.jsx("span",{className:e,children:l.jsx(R,{size:n})})}const{useCallback:w,useState:O,useMemo:T}=h;function C(t){const[,n]=d(t),[e,o]=O(""),r=T(()=>m(n,300),[n]);return[w(a=>{o(a.target.value),r(a.target.value)},[r]),e]}const z="_input_16a1f_1",P={input:z};function L(t){const[n,e]=C(t.textAtom);return l.jsx("input",{className:P.input,type:"text",value:e,onChange:n,placeholder:t.placeholder})}export{$ as R,L as T,R as a};

View File

@ -1 +0,0 @@
import{r as g,R as c,k as i,c as d,j as l,V as h,i as m}from"./index-3e6aad90.js";import{d as v}from"./debounce-c1ba2006.js";function p(){return p=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var e=arguments[n];for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o])}return t},p.apply(this,arguments)}function x(t,n){if(t==null)return{};var e=_(t,n),o,r;if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(r=0;r<a.length;r++)o=a[r],!(n.indexOf(o)>=0)&&Object.prototype.propertyIsEnumerable.call(t,o)&&(e[o]=t[o])}return e}function _(t,n){if(t==null)return{};var e={},o=Object.keys(t),r,a;for(a=0;a<o.length;a++)r=o[a],!(n.indexOf(r)>=0)&&(e[r]=t[r]);return e}var u=g.forwardRef(function(t,n){var e=t.color,o=e===void 0?"currentColor":e,r=t.size,a=r===void 0?24:r,s=x(t,["color","size"]);return c.createElement("svg",p({ref:n,xmlns:"http://www.w3.org/2000/svg",width:a,height:a,viewBox:"0 0 24 24",fill:"none",stroke:o,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},s),c.createElement("polyline",{points:"23 4 23 10 17 10"}),c.createElement("path",{d:"M20.49 15a9 9 0 1 1-2.12-9.36L23 10"}))});u.propTypes={color:i.string,size:i.oneOfType([i.string,i.number])};u.displayName="RotateCw";const b=u,y="_rotate_1dspl_1",R="_isRotating_1dspl_5",w="_rotating_1dspl_1",f={rotate:y,isRotating:R,rotating:w};function $(t){const n=t.size||16,e=d(f.rotate,{[f.isRotating]:t.isRotating});return l("span",{className:e,children:l(b,{size:n})})}const{useCallback:O,useState:j,useMemo:T}=m;function C(t){const[,n]=h(t),[e,o]=j(""),r=T(()=>v(n,300),[n]);return[O(s=>{o(s.target.value),r(s.target.value)},[r]),e]}const k="_input_16a1f_1",z={input:k};function L(t){const[n,e]=C(t.textAtom);return l("input",{className:z.input,type:"text",value:e,onChange:n,placeholder:t.placeholder})}export{$ as R,L as T,b as a};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{r as c,R as l,k as a}from"./index-3e6aad90.js";function s(){return s=Object.assign||function(r){for(var o=1;o<arguments.length;o++){var t=arguments[o];for(var e in t)Object.prototype.hasOwnProperty.call(t,e)&&(r[e]=t[e])}return r},s.apply(this,arguments)}function v(r,o){if(r==null)return{};var t=u(r,o),e,n;if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(r);for(n=0;n<i.length;n++)e=i[n],!(o.indexOf(e)>=0)&&Object.prototype.propertyIsEnumerable.call(r,e)&&(t[e]=r[e])}return t}function u(r,o){if(r==null)return{};var t={},e=Object.keys(r),n,i;for(i=0;i<e.length;i++)n=e[i],!(o.indexOf(n)>=0)&&(t[n]=r[n]);return t}var p=c.forwardRef(function(r,o){var t=r.color,e=t===void 0?"currentColor":t,n=r.size,i=n===void 0?24:n,f=v(r,["color","size"]);return l.createElement("svg",s({ref:o,xmlns:"http://www.w3.org/2000/svg",width:i,height:i,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},f),l.createElement("polyline",{points:"6 9 12 15 18 9"}))});p.propTypes={color:a.string,size:a.oneOfType([a.string,a.number])};p.displayName="ChevronDown";const h=p;export{h as C};
import{r as c,R as p,P as a}from"./index-aa3f8ed9.js";function s(){return s=Object.assign||function(r){for(var o=1;o<arguments.length;o++){var t=arguments[o];for(var e in t)Object.prototype.hasOwnProperty.call(t,e)&&(r[e]=t[e])}return r},s.apply(this,arguments)}function v(r,o){if(r==null)return{};var t=u(r,o),e,n;if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(r);for(n=0;n<i.length;n++)e=i[n],!(o.indexOf(e)>=0)&&Object.prototype.propertyIsEnumerable.call(r,e)&&(t[e]=r[e])}return t}function u(r,o){if(r==null)return{};var t={},e=Object.keys(r),n,i;for(i=0;i<e.length;i++)n=e[i],!(o.indexOf(n)>=0)&&(t[n]=r[n]);return t}var l=c.forwardRef(function(r,o){var t=r.color,e=t===void 0?"currentColor":t,n=r.size,i=n===void 0?24:n,f=v(r,["color","size"]);return p.createElement("svg",s({ref:o,xmlns:"http://www.w3.org/2000/svg",width:i,height:i,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},f),p.createElement("polyline",{points:"6 9 12 15 18 9"}))});l.propTypes={color:a.string,size:a.oneOfType([a.string,a.number])};l.displayName="ChevronDown";const h=l;export{h as C};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,7 @@
var f=new Map;function s(t){if(f.has(t))return f.get(t);var a=v(t);return f.set(t,a),a}var v=function(){var t=null;try{t=document.createElement("canvas").getContext("2d")}catch{}if(!t)return function(){return!1};var a=25,e=20,u=Math.floor(a/2);return t.font=u+"px Arial, Sans-Serif",t.textBaseline="top",t.canvas.width=e*2,t.canvas.height=a,function(n){t.clearRect(0,0,e*2,a),t.fillStyle="#FF0000",t.fillText(n,0,22),t.fillStyle="#0000FF",t.fillText(n,e,22);for(var l=t.getImageData(0,0,e,a).data,o=l.length,r=0;r<o&&!l[r+3];r+=4);if(r>=o)return!1;var c=e+r/4%e,p=Math.floor(r/4/e),i=t.getImageData(c,p,1,1).data;return!(l[r]!==i[0]||l[r+2]!==i[2]||t.measureText(n).width>=e)}}();function E(t="Twemoji Country Flags",a="https://cdn.jsdelivr.net/npm/country-flag-emoji-polyfill@0.1/dist/TwemojiCountryFlags.woff2"){if(s("😊")&&!s("🇨🇭")){const e=document.createElement("style");return e.textContent=`@font-face {
font-family: "${t}";
unicode-range: U+1F1E6-1F1FF, U+1F3F4, U+E0062-E0063, U+E0065, U+E0067,
U+E006C, U+E006E, U+E0073-E0074, U+E0077, U+E007F;
src: url('${a}') format('woff2');
font-display: swap;
}`,document.head.appendChild(e),!0}return!1}export{E as polyfillCountryFlagEmojis};

View File

@ -1,2 +1,2 @@
import{E as w,G as D,H as u}from"./index-3e6aad90.js";const v="/logs",L=new TextDecoder("utf-8"),M=()=>Math.floor((1+Math.random())*65536).toString(16);let h=!1,i=!1,f="",s,g;function m(e,n){let t;try{t=JSON.parse(e)}catch{console.log("JSON.parse error",JSON.parse(e))}const r=new Date,l=$(r);t.time=l,t.id=+r-0+M(),t.even=h=!h,n(t)}function $(e){const n=e.getFullYear()%100,t=u(e.getMonth()+1,2),r=u(e.getDate(),2),l=u(e.getHours(),2),o=u(e.getMinutes(),2),c=u(e.getSeconds(),2);return`${n}-${t}-${r} ${l}:${o}:${c}`}function p(e,n){return e.read().then(({done:t,value:r})=>{const l=L.decode(r,{stream:!t});f+=l;const o=f.split(`
`),c=o[o.length-1];for(let d=0;d<o.length-1;d++)m(o[d],n);if(t){m(c,n),f="",console.log("GET /logs streaming done"),i=!1;return}else f=c;return p(e,n)})}function S(e){const n=Object.keys(e);return n.sort(),n.map(t=>e[t]).join("|")}let b,a;function k(e,n){if(e.logLevel==="uninit"||i||s&&s.readyState===1)return;g=n;const t=w(e,v);s=new WebSocket(t),s.addEventListener("error",()=>{y(e,n)}),s.addEventListener("message",function(r){m(r.data,n)})}function H(){s.close(),a&&a.abort()}function O(e){!g||!s||(s.close(),i=!1,k(e,g))}function y(e,n){if(a&&S(e)!==b)a.abort();else if(i)return;i=!0,b=S(e),a=new AbortController;const t=a.signal,{url:r,init:l}=D(e);fetch(r+v+"?level="+e.logLevel,{...l,signal:t}).then(o=>{const c=o.body.getReader();p(c,n)},o=>{i=!1,!t.aborted&&console.log("GET /logs error:",o.message)})}export{k as f,O as r,H as s};
import{J as L,K as w,L as u}from"./index-aa3f8ed9.js";const v="/logs",D=new TextDecoder("utf-8"),M=()=>Math.floor((1+Math.random())*65536).toString(16);let h=!1,i=!1,f="",s,g;function m(e,n){let t;try{t=JSON.parse(e)}catch{console.log("JSON.parse error",JSON.parse(e))}const r=new Date,l=$(r);t.time=l,t.id=+r-0+M(),t.even=h=!h,n(t)}function $(e){const n=e.getFullYear()%100,t=u(e.getMonth()+1,2),r=u(e.getDate(),2),l=u(e.getHours(),2),o=u(e.getMinutes(),2),c=u(e.getSeconds(),2);return`${n}-${t}-${r} ${l}:${o}:${c}`}function p(e,n){return e.read().then(({done:t,value:r})=>{const l=D.decode(r,{stream:!t});f+=l;const o=f.split(`
`),c=o[o.length-1];for(let d=0;d<o.length-1;d++)m(o[d],n);if(t){m(c,n),f="",console.log("GET /logs streaming done"),i=!1;return}else f=c;return p(e,n)})}function S(e){const n=Object.keys(e);return n.sort(),n.map(t=>e[t]).join("|")}let b,a;function k(e,n){if(e.logLevel==="uninit"||i||s&&s.readyState===1)return;g=n;const t=L(e,v);s=new WebSocket(t),s.addEventListener("error",()=>{y(e,n)}),s.addEventListener("message",function(r){m(r.data,n)})}function J(){s.close(),a&&a.abort()}function O(e){!g||!s||(s.close(),i=!1,k(e,g))}function y(e,n){if(a&&S(e)!==b)a.abort();else if(i)return;i=!0,b=S(e),a=new AbortController;const t=a.signal,{url:r,init:l}=w(e);fetch(r+v+"?level="+e.logLevel,{...l,signal:t}).then(o=>{const c=o.body.getReader();p(c,n)},o=>{i=!1,!t.aborted&&console.log("GET /logs error:",o.message)})}export{k as f,O as r,J as s};

View File

@ -1 +1 @@
import{r as g,R as s,k as a}from"./index-3e6aad90.js";function p(){return p=Object.assign||function(t){for(var o=1;o<arguments.length;o++){var r=arguments[o];for(var e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=r[e])}return t},p.apply(this,arguments)}function v(t,o){if(t==null)return{};var r=y(t,o),e,n;if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n<i.length;n++)e=i[n],!(o.indexOf(e)>=0)&&Object.prototype.propertyIsEnumerable.call(t,e)&&(r[e]=t[e])}return r}function y(t,o){if(t==null)return{};var r={},e=Object.keys(t),n,i;for(i=0;i<e.length;i++)n=e[i],!(o.indexOf(n)>=0)&&(r[n]=t[n]);return r}var c=g.forwardRef(function(t,o){var r=t.color,e=r===void 0?"currentColor":r,n=t.size,i=n===void 0?24:n,l=v(t,["color","size"]);return s.createElement("svg",p({ref:o,xmlns:"http://www.w3.org/2000/svg",width:i,height:i,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},l),s.createElement("rect",{x:"6",y:"4",width:"4",height:"16"}),s.createElement("rect",{x:"14",y:"4",width:"4",height:"16"}))});c.propTypes={color:a.string,size:a.oneOfType([a.string,a.number])};c.displayName="Pause";const b=c;function f(){return f=Object.assign||function(t){for(var o=1;o<arguments.length;o++){var r=arguments[o];for(var e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=r[e])}return t},f.apply(this,arguments)}function h(t,o){if(t==null)return{};var r=O(t,o),e,n;if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n<i.length;n++)e=i[n],!(o.indexOf(e)>=0)&&Object.prototype.propertyIsEnumerable.call(t,e)&&(r[e]=t[e])}return r}function O(t,o){if(t==null)return{};var r={},e=Object.keys(t),n,i;for(i=0;i<e.length;i++)n=e[i],!(o.indexOf(n)>=0)&&(r[n]=t[n]);return r}var u=g.forwardRef(function(t,o){var r=t.color,e=r===void 0?"currentColor":r,n=t.size,i=n===void 0?24:n,l=h(t,["color","size"]);return s.createElement("svg",f({ref:o,xmlns:"http://www.w3.org/2000/svg",width:i,height:i,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},l),s.createElement("polygon",{points:"5 3 19 12 5 21 5 3"}))});u.propTypes={color:a.string,size:a.oneOfType([a.string,a.number])};u.displayName="Play";const w=u;export{w as P,b as a};
import{r as g,R as s,P as a}from"./index-aa3f8ed9.js";function f(){return f=Object.assign||function(t){for(var o=1;o<arguments.length;o++){var r=arguments[o];for(var e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=r[e])}return t},f.apply(this,arguments)}function v(t,o){if(t==null)return{};var r=y(t,o),e,n;if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n<i.length;n++)e=i[n],!(o.indexOf(e)>=0)&&Object.prototype.propertyIsEnumerable.call(t,e)&&(r[e]=t[e])}return r}function y(t,o){if(t==null)return{};var r={},e=Object.keys(t),n,i;for(i=0;i<e.length;i++)n=e[i],!(o.indexOf(n)>=0)&&(r[n]=t[n]);return r}var c=g.forwardRef(function(t,o){var r=t.color,e=r===void 0?"currentColor":r,n=t.size,i=n===void 0?24:n,l=v(t,["color","size"]);return s.createElement("svg",f({ref:o,xmlns:"http://www.w3.org/2000/svg",width:i,height:i,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},l),s.createElement("rect",{x:"6",y:"4",width:"4",height:"16"}),s.createElement("rect",{x:"14",y:"4",width:"4",height:"16"}))});c.propTypes={color:a.string,size:a.oneOfType([a.string,a.number])};c.displayName="Pause";const b=c;function p(){return p=Object.assign||function(t){for(var o=1;o<arguments.length;o++){var r=arguments[o];for(var e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=r[e])}return t},p.apply(this,arguments)}function h(t,o){if(t==null)return{};var r=O(t,o),e,n;if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n<i.length;n++)e=i[n],!(o.indexOf(e)>=0)&&Object.prototype.propertyIsEnumerable.call(t,e)&&(r[e]=t[e])}return r}function O(t,o){if(t==null)return{};var r={},e=Object.keys(t),n,i;for(i=0;i<e.length;i++)n=e[i],!(o.indexOf(n)>=0)&&(r[n]=t[n]);return r}var u=g.forwardRef(function(t,o){var r=t.color,e=r===void 0?"currentColor":r,n=t.size,i=n===void 0?24:n,l=h(t,["color","size"]);return s.createElement("svg",p({ref:o,xmlns:"http://www.w3.org/2000/svg",width:i,height:i,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},l),s.createElement("polygon",{points:"5 3 19 12 5 21 5 3"}))});u.propTypes={color:a.string,size:a.oneOfType([a.string,a.number])};u.displayName="Play";const w=u;export{w as P,b as a};

View File

@ -1 +1 @@
import{i as r}from"./index-3e6aad90.js";const{useState:s,useRef:u,useCallback:a,useLayoutEffect:c}=r;function d(){const t=u(null),[n,i]=s(200),e=a(()=>{const{top:o}=t.current.getBoundingClientRect();i(window.innerHeight-o)},[]);return c(()=>(e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}),[e]),[t,n]}export{d as u};
import{h as r}from"./index-aa3f8ed9.js";const{useState:s,useRef:u,useCallback:a,useLayoutEffect:c}=r;function d(){const t=u(null),[n,i]=s(200),e=a(()=>{const{top:o}=t.current.getBoundingClientRect();i(window.innerHeight-o)},[]);return c(()=>(e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}),[e]),[t,n]}export{d as u};

View File

@ -14,8 +14,8 @@
<meta name="application-name" content="yacd" />
<meta name="description" content="Yet Another Clash Dashboard" />
<title>yacd</title>
<script type="module" crossorigin src="./assets/index-3e6aad90.js"></script>
<link rel="stylesheet" href="./assets/index-8c12d331.css">
<script type="module" crossorigin src="./assets/index-aa3f8ed9.js"></script>
<link rel="stylesheet" href="./assets/index-58e8cd5b.css">
<link rel="manifest" href="./manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="./registerSW.js"></script></head>
<body>
<div id="app" data-base-url="http://127.0.0.1:9090"></div>

File diff suppressed because one or more lines are too long

View File

@ -368,15 +368,18 @@ Thread.new{
Value['interface-name']='${24}';
end;
if ${19} == 1 then
if '${21}' != '0' then
if '${21}' == '1' then
Value['geodata-mode']=true;
end;
if '${22}' != '0' then
Value['geodata-loader']='${22}';
end;
if '${25}' != '0' then
if '${25}' == '1' then
Value['tcp-concurrent']=true;
end;
if '${34}' == '1' then
Value['unified-delay']=true;
end;
if '${29}' != '0' then
Value['find-process-mode']='${29}';
end;
@ -392,10 +395,7 @@ Thread.new{
end;
if ${16} == 1 then
Value['dns']['ipv6']=true;
#meta core v6 DNS
if ${19} == 1 then
Value['ipv6']=true;
end;
Value['ipv6']=true;
else
Value['dns']['ipv6']=false;
end;
@ -629,6 +629,14 @@ Thread.new{
if File::exist?('/etc/openclash/custom/openclash_custom_domain_dns_policy.list') then
Value_6 = YAML.load_file('/etc/openclash/custom/openclash_custom_domain_dns_policy.list');
if Value_6 != false and not Value_6.nil? then
if ${19} != 1 then
Value_6.each{|k,v|
if v.class == "Array" then
Value_6.delete(k);
puts '${LOGTIME} Warning: Skip the nameserver-policy that Core not Support【' + k + '】'
end;
}
end;
if Value['dns'].has_key?('nameserver-policy') and not Value['dns']['nameserver-policy'].to_a.empty? then
Value['dns']['nameserver-policy'].merge!(Value_6);
else

View File

@ -42,8 +42,14 @@ if [ ! -z "$UPDATE_CONFIG_FILE" ]; then
fi
if [ -z "$CONFIG_FILE" ]; then
CONFIG_FILE="/etc/openclash/config/$(ls -lt /etc/openclash/config/ | grep -E '.yaml|.yml' | head -n 1 |awk '{print $9}')"
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
for file_name in /etc/openclash/config/*
do
if [ -f "$file_name" ]; then
CONFIG_FILE=$file_name
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
break
fi
done
fi
if [ -z "$CONFIG_NAME" ]; then

View File

@ -44,7 +44,7 @@ cfg_groups_set()
sed -i "s/new_servers_group \'${old_name_cfg}\'/new_servers_group \'${name}\'/g" $CFG_FILE 2>/dev/null
sed -i "s/relay_groups \'${old_name_cfg}\'/relay_groups \'${name}\'/g" $CFG_FILE 2>/dev/null
#第三方规则处理
OTHER_RULE_NAMES=("GlobalTV" "AsianTV" "Proxy" "Youtube" "Bilibili" "Bahamut" "HBOGo" "HBOMax" "Pornhub" "Apple" "GoogleFCM" "Scholar" "Microsoft" "Netflix" "Disney" "Spotify" "Steam" "Speedtest" "Telegram" "PayPal" "Netease_Music" "AdBlock" "Domestic" "Others" "miHoYo" "ChatGPT" "AppleTV" "Crypto" "Discord")
OTHER_RULE_NAMES=("GlobalTV" "AsianTV" "Proxy" "Youtube" "Bilibili" "Bahamut" "HBOGo" "HBOMax" "Pornhub" "Apple" "GoogleFCM" "Scholar" "Microsoft" "Netflix" "Disney" "Spotify" "Steam" "Speedtest" "Telegram" "PayPal" "Netease_Music" "AdBlock" "Domestic" "Others" "miHoYo" "OpenAI" "AppleTV" "Crypto" "Discord" "Anti IP")
for i in ${OTHER_RULE_NAMES[@]}; do
sed -i "s/option ${i} \'${old_name_cfg}\'/option ${i} \'${name}\'/g" $CFG_FILE 2>/dev/null
done 2>/dev/null

View File

@ -9,7 +9,13 @@ if [ ! -z "$UPDATE_CONFIG_FILE" ]; then
fi
if [ -z "$CFG_FILE" ]; then
CFG_FILE="/etc/openclash/config/$(ls -lt /etc/openclash/config/ | grep -E '.yaml|.yml' | head -n 1 |awk '{print $9}')"
for file_name in /etc/openclash/config/*
do
if [ -f "$file_name" ]; then
CFG_FILE=$file_name
break
fi
done
fi
if [ -f "$CFG_FILE" ]; then

View File

@ -27,8 +27,14 @@ if [ -n "$UPDATE_CONFIG_FILE" ]; then
fi
if [ -z "$CONFIG_FILE" ]; then
CONFIG_FILE="/etc/openclash/config/$(ls -lt /etc/openclash/config/ | grep -E '.yaml|.yml' | head -n 1 |awk '{print $9}')"
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
for file_name in /etc/openclash/config/*
do
if [ -f "$file_name" ]; then
CONFIG_FILE=$file_name
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
break
fi
done
fi
if [ -z "$CONFIG_NAME" ]; then

View File

@ -38,8 +38,14 @@ if [ ! -z "$UPDATE_CONFIG_FILE" ]; then
fi
if [ -z "$CONFIG_FILE" ]; then
CONFIG_FILE="/etc/openclash/config/$(ls -lt /etc/openclash/config/ | grep -E '.yaml|.yml' | head -n 1 |awk '{print $9}')"
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
for file_name in /etc/openclash/config/*
do
if [ -f "$file_name" ]; then
CONFIG_FILE=$file_name
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
break
fi
done
fi
if [ -z "$CONFIG_NAME" ]; then

View File

@ -35,8 +35,14 @@ if [ ! -z "$UPDATE_CONFIG_FILE" ]; then
fi
if [ -z "$CONFIG_FILE" ]; then
CONFIG_FILE="/etc/openclash/config/$(ls -lt /etc/openclash/config/ | grep -E '.yaml|.yml' | head -n 1 |awk '{print $9}')"
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
for file_name in /etc/openclash/config/*
do
if [ -f "$file_name" ]; then
CONFIG_FILE=$file_name
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
break
fi
done
fi
if [ -z "$CONFIG_NAME" ]; then
@ -1499,7 +1505,7 @@ cat >> "$SERVER_FILE" <<-EOF
- Proxy
EOF
cat >> "$SERVER_FILE" <<-EOF
- name: ChatGPT
- name: OpenAI
type: select
proxies:
- Proxy
@ -1758,6 +1764,20 @@ cat >> "$SERVER_FILE" <<-EOF
- REJECT
- DIRECT
- Proxy
- name: Anti IP
type: select
proxies:
- DIRECT
- Proxy
EOF
cat /tmp/Proxy_Server >> $SERVER_FILE 2>/dev/null
if [ -f "/tmp/Proxy_Provider" ]; then
cat >> "$SERVER_FILE" <<-EOF
use:
EOF
fi
cat /tmp/Proxy_Provider >> $SERVER_FILE 2>/dev/null
cat >> "$SERVER_FILE" <<-EOF
- name: Asian TV
type: select
proxies:
@ -1877,7 +1897,7 @@ ${uci_set}AppleTV="Apple TV"
${uci_set}GoogleFCM="Google FCM"
${uci_set}Scholar="Scholar"
${uci_set}Microsoft="Microsoft"
${uci_set}ChatGPT="ChatGPT"
${uci_set}OpenAI="OpenAI"
${uci_set}Netflix="Netflix"
${uci_set}Discovery="Discovery Plus"
${uci_set}DAZN="DAZN"
@ -1886,6 +1906,7 @@ ${uci_set}Spotify="Spotify"
${uci_set}Steam="Steam"
${uci_set}miHoYo="miHoYo"
${uci_set}AdBlock="AdBlock"
${uci_set}AntiIP="Anti IP"
${uci_set}Speedtest="Speedtest"
${uci_set}Telegram="Telegram"
${uci_set}Crypto="Crypto"
@ -1910,7 +1931,7 @@ ${uci_set}Others="Others"
${UCI_DEL_LIST}="Netflix" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Netflix" >/dev/null 2>&1
${UCI_DEL_LIST}="Discovery Plus" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Discovery Plus" >/dev/null 2>&1
${UCI_DEL_LIST}="DAZN" >/dev/null 2>&1 && ${UCI_ADD_LIST}="DAZN" >/dev/null 2>&1
${UCI_DEL_LIST}="ChatGPT" >/dev/null 2>&1 && ${UCI_ADD_LIST}="ChatGPT" >/dev/null 2>&1
${UCI_DEL_LIST}="OpenAI" >/dev/null 2>&1 && ${UCI_ADD_LIST}="OpenAI" >/dev/null 2>&1
${UCI_DEL_LIST}="Apple TV" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Apple TV" >/dev/null 2>&1
${UCI_DEL_LIST}="Google FCM" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Google FCM" >/dev/null 2>&1
${UCI_DEL_LIST}="Scholar" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Scholar" >/dev/null 2>&1
@ -1923,6 +1944,7 @@ ${uci_set}Others="Others"
${UCI_DEL_LIST}="Discord" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Discord" >/dev/null 2>&1
${UCI_DEL_LIST}="PayPal" >/dev/null 2>&1 && ${UCI_ADD_LIST}="PayPal" >/dev/null 2>&1
${UCI_DEL_LIST}="Speedtest" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Speedtest" >/dev/null 2>&1
${UCI_DEL_LIST}="Anti IP" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Anti IP" >/dev/null 2>&1
${UCI_DEL_LIST}="Others" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Others" >/dev/null 2>&1
}
elif [ "$rule_sources" = "ConnersHua_return" ] && [ "$servers_if_update" != "1" ] && [ -z "$if_game_proxy" ]; then

View File

@ -559,7 +559,7 @@ yml_other_set()
if defined? Value_2 then
Value_2.each{|x|
if ${10} != 1 then
if x =~ /(^GEOSITE,|^AND,|^OR,|^NOT,|^IP-SUFFIX,|^SRC-IP-SUFFIX,|^IN-TYPE,|^SUB-RULE,|PORT,[0-9]+\/+|PORT,[0-9]+-+)/ or x.split(',')[-1] == 'tcp' or x.split(',')[-1] == 'udp' then
if x =~ /(^GEOSITE,|^AND,|^OR,|^NOT,|^IP-SUFFIX,|^SRC-IP-SUFFIX,|^IN-TYPE,|^IN-USER,|^IN-NAME,|^NETWORK,|^UID,|^SUB-RULE,|PORT,[0-9]+\/+|PORT,[0-9]+-+)/ or x.split(',')[-1] == 'tcp' or x.split(',')[-1] == 'udp' then
puts '${LOGTIME} Warning: Skip the Custom Rule that Core not Support【' + x + '】'
next
end;
@ -937,9 +937,10 @@ yml_other_rules_get()
config_get "GoogleFCM" "$section" "GoogleFCM" "DIRECT"
config_get "Discovery" "$section" "Discovery" "$GlobalTV"
config_get "DAZN" "$section" "DAZN" "$GlobalTV"
config_get "ChatGPT" "$section" "ChatGPT" "$Proxy"
config_get "OpenAI" "$section" "OpenAI" "$Proxy"
config_get "AppleTV" "$section" "AppleTV" "$GlobalTV"
config_get "miHoYo" "$section" "miHoYo" "$Domestic"
config_get "AntiIP" "$section" "AntiIP" "$Domestic"
}
if [ "$1" != "0" ]; then
@ -988,7 +989,7 @@ if [ "$1" != "0" ]; then
|| [ -z "$(grep -F "$Disney" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Discovery" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$DAZN" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$ChatGPT" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$OpenAI" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Spotify" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Steam" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$miHoYo" /tmp/Proxy_Group)" ]\
@ -1001,6 +1002,7 @@ if [ "$1" != "0" ]; then
|| [ -z "$(grep -F "$PayPal" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Others" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$GoogleFCM" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$AntiIP" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep -F "$Domestic" /tmp/Proxy_Group)" ]; then
LOG_OUT "Warning: Because of The Different Porxy-Group's Name, Stop Setting The Other Rules!"
yml_other_set "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "${10}" "${11}" "${12}" "${13}"
@ -1033,69 +1035,71 @@ if [ "$1" != "0" ]; then
Value['script']=Value_1['script'];
Value['rules']=Value_1['rules'];
Value['rules'].to_a.collect!{|x|
x.to_s.gsub(/,Bilibili,Asian TV$/, ',Bilibili,$Bilibili#delete_')
.gsub(/,Bahamut,Global TV$/, ',Bahamut,$Bahamut#delete_')
.gsub(/,HBO Max,Global TV$/, ',HBO Max,$HBOMax#delete_')
.gsub(/,HBO Go,Global TV$/, ',HBO Go,$HBOGo#delete_')
.gsub(/,Discovery Plus,Global TV$/, ',Discovery Plus,$Discovery#delete_')
.gsub(/,DAZN,Global TV$/, ',DAZN,$DAZN#delete_')
.gsub(/,Pornhub,Global TV$/, ',Pornhub,$Pornhub#delete_')
.gsub(/,Global TV$/, ',$GlobalTV#delete_')
.gsub(/,Asian TV$/, ',$AsianTV#delete_')
.gsub(/,Proxy$/, ',$Proxy#delete_')
.gsub(/,YouTube$/, ',$Youtube#delete_')
.gsub(/,Apple$/, ',$Apple#delete_')
.gsub(/,Apple TV$/, ',$AppleTV#delete_')
.gsub(/,Scholar$/, ',$Scholar#delete_')
.gsub(/,Netflix$/, ',$Netflix#delete_')
.gsub(/,Disney$/, ',$Disney#delete_')
.gsub(/,Spotify$/, ',$Spotify#delete_')
.gsub(/,ChatGPT$/, ',$ChatGPT#delete_')
.gsub(/,Steam$/, ',$Steam#delete_')
.gsub(/,miHoYo$/, ',$miHoYo#delete_')
.gsub(/,AdBlock$/, ',$AdBlock#delete_')
.gsub(/,Speedtest$/, ',$Speedtest#delete_')
.gsub(/,Telegram$/, ',$Telegram#delete_')
.gsub(/,Crypto$/, ',$Crypto#delete_')
.gsub(/,Discord$/, ',$Discord#delete_')
.gsub(/,Microsoft$/, ',$Microsoft#delete_')
.to_s.gsub(/,PayPal$/, ',$PayPal#delete_')
.gsub(/,Domestic$/, ',$Domestic#delete_')
.gsub(/,Others$/, ',$Others#delete_')
.gsub(/,Google FCM$/, ',$GoogleFCM#delete_')
x.to_s.gsub(/,[\s]?Bilibili,[\s]?Asian TV$/, ', Bilibili, $Bilibili#delete_')
.gsub(/,[\s]?Bahamut,[\s]?Global TV$/, ', Bahamut, $Bahamut#delete_')
.gsub(/,[\s]?HBO Max,[\s]?Global TV$/, ', HBO Max, $HBOMax#delete_')
.gsub(/,[\s]?HBO Go,[\s]?Global TV$/, ', HBO Go, $HBOGo#delete_')
.gsub(/,[\s]?Discovery Plus,[\s]?Global TV$/, ', Discovery Plus, $Discovery#delete_')
.gsub(/,[\s]?DAZN,[\s]?Global TV$/, ', DAZN, $DAZN#delete_')
.gsub(/,[\s]?Pornhub,[\s]?Global TV$/, ', Pornhub, $Pornhub#delete_')
.gsub(/,[\s]?Anti IP$/, ', $AntiIP#delete_')
.gsub(/,[\s]?Global TV$/, ', $GlobalTV#delete_')
.gsub(/,[\s]?Asian TV$/, ', $AsianTV#delete_')
.gsub(/,[\s]?Proxy$/, ', $Proxy#delete_')
.gsub(/,[\s]?YouTube$/, ', $Youtube#delete_')
.gsub(/,[\s]?Apple$/, ', $Apple#delete_')
.gsub(/,[\s]?Apple TV$/, ', $AppleTV#delete_')
.gsub(/,[\s]?Scholar$/, ', $Scholar#delete_')
.gsub(/,[\s]?Netflix$/, ', $Netflix#delete_')
.gsub(/,[\s]?Disney$/, ', $Disney#delete_')
.gsub(/,[\s]?Spotify$/, ', $Spotify#delete_')
.gsub(/,[\s]?OpenAI$/, ', $OpenAI#delete_')
.gsub(/,[\s]?Steam$/, ', $Steam#delete_')
.gsub(/,[\s]?miHoYo$/, ', $miHoYo#delete_')
.gsub(/,[\s]?AdBlock$/, ', $AdBlock#delete_')
.gsub(/,[\s]?Speedtest$/, ', $Speedtest#delete_')
.gsub(/,[\s]?Telegram$/, ', $Telegram#delete_')
.gsub(/,[\s]?Crypto$/, ', $Crypto#delete_')
.gsub(/,[\s]?Discord$/, ', $Discord#delete_')
.gsub(/,[\s]?Microsoft$/, ', $Microsoft#delete_')
.to_s.gsub(/,[\s]?PayPal$/, ', $PayPal#delete_')
.gsub(/,[\s]?Domestic$/, ', $Domestic#delete_')
.gsub(/,[\s]?Others$/, ', $Others#delete_')
.gsub(/,[\s]?Google FCM$/, ', $GoogleFCM#delete_')
.gsub(/#delete_/, '')
};
Value['script']['code'].to_s.gsub!(/\"Bilibili\": \"Asian TV\"/,'\"Bilibili\": \"$Bilibili#delete_\"')
.gsub!(/\"Bahamut\": \"Global TV\"/,'\"Bahamut\": \"$Bahamut#delete_\"')
.gsub!(/\"HBO Max\": \"Global TV\"/,'\"HBO Max\": \"$HBOMax#delete_\"')
.gsub!(/\"HBO Go\": \"Global TV\"/,'\"HBO Go\": \"$HBOGo#delete_\"')
.gsub!(/\"Discovery Plus\": \"Global TV\"/,'\"Discovery Plus\": \"$Discovery#delete_\"')
.gsub!(/\"DAZN\": \"Global TV\"/,'\"DAZN\": \"$DAZN#delete_\"')
.gsub!(/\"Pornhub\": \"Global TV\"/,'\"Pornhub\": \"$Pornhub#delete_\"')
.gsub!(/: \"Global TV\"/,': \"$GlobalTV#delete_\"')
.gsub!(/: \"Asian TV\"/,': \"$AsianTV#delete_\"')
.gsub!(/: \"Proxy\"/,': \"$Proxy#delete_\"')
.gsub!(/: \"YouTube\"/,': \"$Youtube#delete_\"')
.gsub!(/: \"Apple\"/,': \"$Apple#delete_\"')
.gsub!(/: \"Apple TV\"/,': \"$AppleTV#delete_\"')
.gsub!(/: \"Scholar\"/,': \"$Scholar#delete_\"')
.gsub!(/: \"Netflix\"/,': \"$Netflix#delete_\"')
.gsub!(/: \"Disney\"/,': \"$Disney#delete_\"')
.gsub!(/: \"Spotify\"/,': \"$Spotify#delete_\"')
.gsub!(/: \"ChatGPT\"/,': \"$ChatGPT#delete_\"')
.gsub!(/: \"Steam\"/,': \"$Steam#delete_\"')
.gsub!(/: \"miHoYo\"/,': \"$miHoYo#delete_\"')
.gsub!(/: \"AdBlock\"/,': \"$AdBlock#delete_\"')
.gsub!(/: \"Speedtest\"/,': \"$Speedtest#delete_\"')
.gsub!(/: \"Telegram\"/,': \"$Telegram#delete_\"')
.gsub!(/: \"Crypto\"/,': \"$Crypto#delete_\"')
.gsub!(/: \"Discord\"/,': \"$Discord#delete_\"')
.gsub!(/: \"Microsoft\"/,': \"$Microsoft#delete_\"')
.gsub!(/: \"PayPal\"/,': \"$PayPal#delete_\"')
.gsub!(/: \"Domestic\"/,': \"$Domestic#delete_\"')
.gsub!(/: \"Google FCM\"/,': \"$GoogleFCM#delete_\"')
.gsub!(/return \"Domestic\"$/, 'return \"$Domestic#delete_\"')
.gsub!(/return \"Others\"$/, 'return \"$Others#delete_\"')
Value['script']['code'].to_s.gsub!(/\'Bilibili\': \'Asian TV\'/,'\'Bilibili\': \'$Bilibili#delete_\'')
.gsub!(/\'Bahamut\': \'Global TV\'/,'\'Bahamut\': \'$Bahamut#delete_\'')
.gsub!(/\'HBO Max\': \'Global TV\'/,'\'HBO Max\': \'$HBOMax#delete_\'')
.gsub!(/\'HBO Go\': \'Global TV\'/,'\'HBO Go\': \'$HBOGo#delete_\'')
.gsub!(/\'Discovery Plus\': \'Global TV\'/,'\'Discovery Plus\': \'$Discovery#delete_\'')
.gsub!(/\'DAZN\': \'Global TV\'/,'\'DAZN\': \'$DAZN#delete_\'')
.gsub!(/\'Pornhub\': \'Global TV\'/,'\'Pornhub\': \'$Pornhub#delete_\'')
.gsub!(/: \'Global TV\'/,': \'$GlobalTV#delete_\'')
.gsub!(/: \'Asian TV\'/,': \'$AsianTV#delete_\'')
.gsub!(/: \'Proxy\'/,': \'$Proxy#delete_\'')
.gsub!(/: \'YouTube\'/,': \'$Youtube#delete_\'')
.gsub!(/: \'Apple\'/,': \'$Apple#delete_\'')
.gsub!(/: \'Apple TV\'/,': \'$AppleTV#delete_\'')
.gsub!(/: \'Scholar\'/,': \'$Scholar#delete_\'')
.gsub!(/: \'Netflix\'/,': \'$Netflix#delete_\'')
.gsub!(/: \'Disney\'/,': \'$Disney#delete_\'')
.gsub!(/: \'Spotify\'/,': \'$Spotify#delete_\'')
.gsub!(/: \'OpenAI\'/,': \'$OpenAI#delete_\'')
.gsub!(/: \'Steam\'/,': \'$Steam#delete_\'')
.gsub!(/: \'miHoYo\'/,': \'$miHoYo#delete_\'')
.gsub!(/: \'AdBlock\'/,': \'$AdBlock#delete_\'')
.gsub!(/: \'Speedtest\'/,': \'$Speedtest#delete_\'')
.gsub!(/: \'Telegram\'/,': \'$Telegram#delete_\'')
.gsub!(/: \'Crypto\'/,': \'$Crypto#delete_\'')
.gsub!(/: \'Discord\'/,': \'$Discord#delete_\'')
.gsub!(/: \'Microsoft\'/,': \'$Microsoft#delete_\'')
.gsub!(/: \'PayPal\'/,': \'$PayPal#delete_\'')
.gsub!(/: \'Domestic\'/,': \'$Domestic#delete_\'')
.gsub!(/: \'Google FCM\'/,': \'$GoogleFCM#delete_\'')
.gsub!(/: \'Anti IP\'/,': \'$AntiIP#delete_\'')
.gsub!(/return \'Domestic\'$/, 'return \'$Domestic#delete_\'')
.gsub!(/return \'Others\'$/, 'return \'$Others#delete_\'')
.gsub!(/#delete_/, '');
File.open('$3','w') {|f| YAML.dump(Value, f)};
rescue Exception => e

View File

@ -6,7 +6,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=4.67-4
PKG_VERSION:=4.68-1
PKG_RELEASE:=
PKG_CONFIG_DEPENDS:= \

View File

@ -25,7 +25,6 @@ function index()
entry({"admin", "services", appname, "settings"}, cbi(appname .. "/client/global"), _("Basic Settings"), 1).dependent = true
entry({"admin", "services", appname, "node_list"}, cbi(appname .. "/client/node_list"), _("Node List"), 2).dependent = true
entry({"admin", "services", appname, "node_subscribe"}, cbi(appname .. "/client/node_subscribe"), _("Node Subscribe"), 3).dependent = true
entry({"admin", "services", appname, "auto_switch"}, cbi(appname .. "/client/auto_switch"), _("Auto Switch"), 4).leaf = true
entry({"admin", "services", appname, "other"}, cbi(appname .. "/client/other", {autoapply = true}), _("Other Settings"), 92).leaf = true
if nixio.fs.access("/usr/sbin/haproxy") then
entry({"admin", "services", appname, "haproxy"}, cbi(appname .. "/client/haproxy"), _("Load Balancing"), 93).leaf = true
@ -36,6 +35,7 @@ function index()
entry({"admin", "services", appname, "node_subscribe_config"}, cbi(appname .. "/client/node_subscribe_config")).leaf = true
entry({"admin", "services", appname, "node_config"}, cbi(appname .. "/client/node_config")).leaf = true
entry({"admin", "services", appname, "shunt_rules"}, cbi(appname .. "/client/shunt_rules")).leaf = true
entry({"admin", "services", appname, "socks_config"}, cbi(appname .. "/client/socks_config")).leaf = true
entry({"admin", "services", appname, "acl"}, cbi(appname .. "/client/acl"), _("Access control"), 98).leaf = true
entry({"admin", "services", appname, "acl_config"}, cbi(appname .. "/client/acl_config")).leaf = true
entry({"admin", "services", appname, "log"}, form(appname .. "/client/log"), _("Watch Logs"), 999).leaf = true
@ -50,8 +50,8 @@ function index()
entry({"admin", "services", appname, "server_get_log"}, call("server_get_log")).leaf = true
entry({"admin", "services", appname, "server_clear_log"}, call("server_clear_log")).leaf = true
entry({"admin", "services", appname, "link_add_node"}, call("link_add_node")).leaf = true
entry({"admin", "services", appname, "autoswitch_add_node"}, call("autoswitch_add_node")).leaf = true
entry({"admin", "services", appname, "autoswitch_remove_node"}, call("autoswitch_remove_node")).leaf = true
entry({"admin", "services", appname, "socks_autoswitch_add_node"}, call("socks_autoswitch_add_node")).leaf = true
entry({"admin", "services", appname, "socks_autoswitch_remove_node"}, call("socks_autoswitch_remove_node")).leaf = true
entry({"admin", "services", appname, "get_now_use_node"}, call("get_now_use_node")).leaf = true
entry({"admin", "services", appname, "get_redir_log"}, call("get_redir_log")).leaf = true
entry({"admin", "services", appname, "get_log"}, call("get_log")).leaf = true
@ -110,10 +110,11 @@ function link_add_node()
luci.sys.call("lua /usr/share/passwall/subscribe.lua add log")
end
function autoswitch_add_node()
function socks_autoswitch_add_node()
local id = luci.http.formvalue("id")
local key = luci.http.formvalue("key")
if key and key ~= "" then
local new_list = ucic:get(appname, "@auto_switch[0]", "tcp_node") or {}
if id and id ~= "" and key and key ~= "" then
local new_list = ucic:get(appname, id, "autoswitch_backup_node") or {}
for i = #new_list, 1, -1 do
if (ucic:get(appname, new_list[i], "remarks") or ""):find(key) then
table.remove(new_list, i)
@ -124,25 +125,26 @@ function autoswitch_add_node()
table.insert(new_list, e.id)
end
end
ucic:set_list(appname, "@auto_switch[0]", "tcp_node", new_list)
ucic:set_list(appname, id, "autoswitch_backup_node", new_list)
ucic:commit(appname)
end
luci.http.redirect(api.url("auto_switch"))
luci.http.redirect(api.url("socks_config", id))
end
function autoswitch_remove_node()
function socks_autoswitch_remove_node()
local id = luci.http.formvalue("id")
local key = luci.http.formvalue("key")
if key and key ~= "" then
local new_list = ucic:get(appname, "@auto_switch[0]", "tcp_node") or {}
if id and id ~= "" and key and key ~= "" then
local new_list = ucic:get(appname, id, "autoswitch_backup_node") or {}
for i = #new_list, 1, -1 do
if (ucic:get(appname, new_list[i], "remarks") or ""):find(key) then
table.remove(new_list, i)
end
end
ucic:set_list(appname, "@auto_switch[0]", "tcp_node", new_list)
ucic:set_list(appname, id, "autoswitch_backup_node", new_list)
ucic:commit(appname)
end
luci.http.redirect(api.url("auto_switch"))
luci.http.redirect(api.url("socks_config", id))
end
function get_now_use_node()
@ -313,9 +315,9 @@ function clear_all_nodes()
ucic:set(appname, '@global[0]', "enabled", "0")
ucic:set(appname, '@global[0]', "tcp_node", "nil")
ucic:set(appname, '@global[0]', "udp_node", "nil")
ucic:set_list(appname, "@auto_switch[0]", "tcp_node", {})
ucic:foreach(appname, "socks", function(t)
ucic:delete(appname, t[".name"])
ucic:set_list(appname, t[".name"], "autoswitch_backup_node", {})
end)
ucic:foreach(appname, "haproxy_config", function(t)
ucic:delete(appname, t[".name"])
@ -334,14 +336,7 @@ end
function delete_select_nodes()
local ids = luci.http.formvalue("ids")
local auto_switch_tcp_node_list = ucic:get(appname, "@auto_switch[0]", "tcp_node") or {}
string.gsub(ids, '[^' .. "," .. ']+', function(w)
for i = #auto_switch_tcp_node_list, 1, -1 do
if w == auto_switch_tcp_node_list[i] then
table.remove(auto_switch_tcp_node_list, i)
end
end
ucic:set_list(appname, "@auto_switch[0]", "tcp_node", auto_switch_tcp_node_list)
if (ucic:get(appname, "@global[0]", "tcp_node") or "nil") == w then
ucic:set(appname, '@global[0]', "tcp_node", "nil")
end
@ -352,6 +347,13 @@ function delete_select_nodes()
if t["node"] == w then
ucic:delete(appname, t[".name"])
end
local auto_switch_node_list = ucic:get(appname, t[".name"], "autoswitch_backup_node") or {}
for i = #auto_switch_node_list, 1, -1 do
if w == auto_switch_node_list[i] then
table.remove(auto_switch_node_list, i)
end
end
ucic:set_list(appname, t[".name"], "autoswitch_backup_node", auto_switch_node_list)
end)
ucic:foreach(appname, "haproxy_config", function(t)
if t["lbss"] == w then

View File

@ -1,66 +0,0 @@
local api = require "luci.passwall.api"
local appname = api.appname
local nodes_table = {}
for k, e in ipairs(api.get_valid_nodes()) do
nodes_table[#nodes_table + 1] = e
end
m = Map(appname)
-- [[ Auto Switch Settings ]]--
s = m:section(TypedSection, "auto_switch")
s.anonymous = true
---- Enable
o = s:option(Flag, "enable", translate("Enable"))
o.default = 0
o.rmempty = false
o = s:option(Value, "testing_time", translate("How often to test"), translate("Units:minutes"))
o.datatype = "uinteger"
o.default = 1
o = s:option(Value, "connect_timeout", translate("Timeout seconds"), translate("Units:seconds"))
o.datatype = "uinteger"
o.default = 3
o = s:option(Value, "retry_num", translate("Timeout retry num"))
o.datatype = "uinteger"
o.default = 3
o = s:option(DynamicList, "tcp_node", "TCP " .. translate("List of backup nodes"))
for k, v in pairs(nodes_table) do
if v.node_type == "normal" then
o:value(v.id, v["remark"])
end
end
function o.write(self, section, value)
local t = {}
local t2 = {}
if type(value) == "table" then
local x
for _, x in ipairs(value) do
if x and #x > 0 then
if not t2[x] then
t2[x] = x
t[#t+1] = x
end
end
end
else
t = { value }
end
return DynamicList.write(self, section, t)
end
o = s:option(Flag, "restore_switch", "TCP " .. translate("Restore Switch"), translate("When detects main node is available, switch back to the main node."))
o = s:option(ListValue, "shunt_logic", "TCP " .. translate("If the main node is V2ray/Xray shunt"))
o:value("0", translate("Switch it"))
o:value("1", translate("Applying to the default node"))
o:value("2", translate("Applying to the preproxy node"))
m:append(Template(appname .. "/auto_switch/footer"))
return m

View File

@ -84,42 +84,9 @@ s:tab("Main", translate("Main"))
o = s:taboption("Main", Flag, "enabled", translate("Main switch"))
o.rmempty = false
local auto_switch_tip
local shunt_remark
local current_tcp_node = luci.sys.exec(string.format("[ -f '/tmp/etc/%s/id/TCP' ] && echo -n $(cat /tmp/etc/%s/id/TCP)", appname, appname))
if current_tcp_node and current_tcp_node ~= "" and current_tcp_node ~= "nil" then
local n = uci:get_all(appname, current_tcp_node)
if n then
if tonumber(m:get("@auto_switch[0]", "enable") or 0) == 1 then
if n.protocol == "_shunt" then
local shunt_logic = tonumber(m:get("@auto_switch[0]", "shunt_logic"))
if shunt_logic == 1 or shunt_logic == 2 then
if shunt_logic == 1 then
shunt_remark = "default"
elseif shunt_logic == 2 then
shunt_remark = "main"
end
current_tcp_node = luci.sys.exec(string.format("[ -f '/tmp/etc/%s/id/TCP_%s' ] && echo -n $(cat /tmp/etc/%s/id/TCP_%s)", appname, shunt_remark, appname, shunt_remark))
if current_tcp_node and current_tcp_node ~= "" and current_tcp_node ~= "nil" then
n = uci:get_all(appname, current_tcp_node)
end
end
end
if n then
local remarks = api.get_node_remarks(n)
local url = api.url("node_config", n[".name"])
auto_switch_tip = translatef("Current node: %s", string.format('<a href="%s">%s</a>', url, remarks)) .. "<br />"
end
end
end
end
---- TCP Node
tcp_node = s:taboption("Main", ListValue, "tcp_node", "<a style='color: red'>" .. translate("TCP Node") .. "</a>")
tcp_node:value("nil", translate("Close"))
if not shunt_remark and auto_switch_tip then
tcp_node.description = auto_switch_tip
end
---- UDP Node
udp_node = s:taboption("Main", ListValue, "udp_node", "<a style='color: red'>" .. translate("UDP Node") .. "</a>")
@ -191,9 +158,6 @@ if (has_v2ray or has_xray) and #nodes_table > 0 then
end
o.cfgvalue = get_cfgvalue(v.id, "main_node")
o.write = get_write(v.id, "main_node")
if shunt_remark == "main" and auto_switch_tip then
o.description = auto_switch_tip
end
if (has_v2ray and has_xray) or (v.type == "V2ray" and not has_v2ray) or (v.type == "Xray" and not has_xray) then
type:depends("tcp_node", v.id)
@ -249,9 +213,6 @@ if (has_v2ray or has_xray) and #nodes_table > 0 then
for k1, v1 in pairs(normal_list) do
o:value(v1.id, v1.remark)
end
if shunt_remark == "default" and auto_switch_tip then
o.description = auto_switch_tip
end
local id = "default_proxy_tag"
o = s:taboption("Main", ListValue, vid .. "-" .. id, string.format('* <a style="color:red">%s</a>', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node."))
@ -521,11 +482,15 @@ o = s:taboption("Main", Flag, "socks_enabled", "Socks " .. translate("Main switc
o.rmempty = false
s = m:section(TypedSection, "socks", translate("Socks Config"))
s.template = "cbi/tblsection"
s.anonymous = true
s.addremove = true
s.template = "cbi/tblsection"
s.extedit = api.url("socks_config", "%s")
function s.create(e, t)
TypedSection.create(e, api.gen_short_uuid())
local uuid = api.gen_short_uuid()
t = uuid
TypedSection.create(e, t)
luci.http.redirect(e.extedit:format(t))
end
o = s:option(DummyValue, "status", translate("Status"))

View File

@ -37,6 +37,11 @@ function s.remove(e, t)
if s["node"] == t then
m:del(s[".name"])
end
for k, v in ipairs(m:get(s[".name"], "autoswitch_backup_node") or {}) do
if v and v == t then
sys.call(string.format("uci -q del_list %s.%s.autoswitch_backup_node='%s'", appname, s[".name"], v))
end
end
end)
m.uci:foreach(appname, "haproxy_config", function(s)
if s["lbss"] and s["lbss"] == t then
@ -51,11 +56,6 @@ function s.remove(e, t)
m:set(s[".name"], "udp_node", "default")
end
end)
for k, v in ipairs(m:get("@auto_switch[0]", "tcp_node") or {}) do
if v and v == t then
sys.call(string.format("uci -q del_list %s.@auto_switch[0].tcp_node='%s'", appname, v))
end
end
TypedSection.remove(e, t)
local new_node = "nil"
local node0 = m:get("@nodes[0]") or nil

View File

@ -0,0 +1,119 @@
local api = require "luci.passwall.api"
local appname = api.appname
local uci = api.uci
local has_v2ray = api.is_finded("v2ray")
local has_xray = api.is_finded("xray")
m = Map(appname)
local nodes_table = {}
for k, e in ipairs(api.get_valid_nodes()) do
nodes_table[#nodes_table + 1] = e
end
s = m:section(NamedSection, arg[1], translate("Socks Config"), translate("Socks Config"))
s.addremove = false
s.dynamic = false
---- Enable
o = s:option(Flag, "enabled", translate("Enable"))
o.default = 1
o.rmempty = false
local auto_switch_tip
local current_node_file = string.format("/tmp/etc/%s/id/socks_%s", appname, arg[1])
local current_node = luci.sys.exec(string.format("[ -f '%s' ] && echo -n $(cat %s)", current_node_file, current_node_file))
if current_node and current_node ~= "" and current_node ~= "nil" then
local n = uci:get_all(appname, current_node)
if n then
if tonumber(m:get(arg[1], "enable_autoswitch") or 0) == 1 then
if n then
local remarks = api.get_node_remarks(n)
local url = api.url("node_config", n[".name"])
auto_switch_tip = translatef("Current node: %s", string.format('<a href="%s">%s</a>', url, remarks)) .. "<br />"
end
end
end
end
socks_node = s:option(ListValue, "node", translate("Node"))
if auto_switch_tip then
socks_node.description = auto_switch_tip
end
local n = 1
uci:foreach(appname, "socks", function(s)
if s[".name"] == section then
return false
end
n = n + 1
end)
o = s:option(Value, "port", "Socks " .. translate("Listen Port"))
o.default = n + 1080
o.datatype = "port"
o.rmempty = false
if has_v2ray or has_xray then
o = s:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
o.default = 0
o.datatype = "port"
end
o = s:option(Flag, "enable_autoswitch", translate("Auto Switch"))
o.default = 0
o.rmempty = false
o = s:option(Value, "autoswitch_testing_time", translate("How often to test"), translate("Units:minutes"))
o.datatype = "uinteger"
o.default = 1
o:depends("enable_autoswitch", true)
o = s:option(Value, "autoswitch_connect_timeout", translate("Timeout seconds"), translate("Units:seconds"))
o.datatype = "uinteger"
o.default = 3
o:depends("enable_autoswitch", true)
o = s:option(Value, "autoswitch_retry_num", translate("Timeout retry num"))
o.datatype = "uinteger"
o.default = 1
o:depends("enable_autoswitch", true)
autoswitch_backup_node = s:option(DynamicList, "autoswitch_backup_node", translate("List of backup nodes"))
autoswitch_backup_node:depends("enable_autoswitch", true)
function o.write(self, section, value)
local t = {}
local t2 = {}
if type(value) == "table" then
local x
for _, x in ipairs(value) do
if x and #x > 0 then
if not t2[x] then
t2[x] = x
t[#t+1] = x
end
end
end
else
t = { value }
end
return DynamicList.write(self, section, t)
end
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)
o = s:option(Value, "autoswitch_probe_url", translate("Probe URL"), translate("The URL used to detect the connection status."))
o.default = "https://www.google.com/generate_204"
o:depends("enable_autoswitch", true)
for k, v in pairs(nodes_table) do
if v.node_type == "normal" then
autoswitch_backup_node:value(v.id, v["remark"])
socks_node:value(v.id, v["remark"])
end
end
m:append(Template(appname .. "/socks_auto_switch/footer"))
return m

View File

@ -1,6 +1,5 @@
<%
local api = require "luci.passwall.api"
local auto_switch = api.uci_get_type("auto_switch", "enable", 0)
-%>
<script type="text/javascript">
//<![CDATA[

View File

@ -4,20 +4,20 @@ local api = require "luci.passwall.api"
<script type="text/javascript">
//<![CDATA[
let socks_id = window.location.pathname.substring(window.location.pathname.lastIndexOf("/") + 1)
function add_node_by_key() {
var key = prompt("<%:Please enter the node keyword, pay attention to distinguish between spaces, uppercase and lowercase.%>", "");
if (key) {
window.location.href = '<%=api.url("autoswitch_add_node")%>' + "?key=" + key;
window.location.href = '<%=api.url("socks_autoswitch_add_node")%>' + "?id=" + socks_id + "&key=" + key;
}
}
function remove_node_by_key() {
var key = prompt("<%:Please enter the node keyword, pay attention to distinguish between spaces, uppercase and lowercase.%>", "");
if (key) {
window.location.href = '<%=api.url("autoswitch_remove_node")%>' + "?key=" + key;
window.location.href = '<%=api.url("socks_autoswitch_remove_node")%>' + "?id=" + socks_id + "&key=" + key;
}
}
//]]>
</script>
<input class="btn cbi-button cbi-button-add" type="button" onclick="add_node_by_key()" value="<%:Add nodes to the standby node list by keywords%>" />
<input class="btn cbi-button cbi-button-remove" type="button" onclick="remove_node_by_key()" value="<%:Delete nodes in the standby node list by keywords%>" />
<input class="btn cbi-button cbi-button-remove" type="button" onclick="remove_node_by_key()" value="<%:Delete nodes in the standby node list by keywords%>" />

View File

@ -77,13 +77,6 @@ config global_subscribe
list filter_discard_list 'QQ群'
list filter_discard_list '官网'
config auto_switch
option enable '0'
option testing_time '1'
option connect_timeout '3'
option retry_num '3'
option shunt_logic '1'
config nodes 'myshunt'
option remarks '分流总节点'
option type 'Xray'

View File

@ -929,56 +929,6 @@ run_redir() {
return 0
}
node_switch() {
local flag new_node shunt_logic log_output
eval_set_val $@
[ -n "$flag" ] && [ -n "$new_node" ] && {
flag=$(echo $flag | tr 'A-Z' 'a-z')
FLAG=$(echo $flag | tr 'a-z' 'A-Z')
[ -n "$log_output" ] || LOG_FILE="/dev/null"
local node=$2
pgrep -af "${TMP_PATH}" | awk -v P1="${FLAG}" 'BEGIN{IGNORECASE=1}$0~P1 && !/acl\/|acl_/{print $1}' | xargs kill -9 >/dev/null 2>&1
rm -rf $TMP_PATH/${FLAG}*
local config_file="${FLAG}.json"
local log_file="${FLAG}.log"
local port=$(cat $TMP_PORT_PATH/${FLAG})
[ "$shunt_logic" != "0" ] && {
local node=$(config_t_get global ${flag}_node nil)
[ "$(config_n_get $node protocol nil)" = "_shunt" ] && {
if [ "$shunt_logic" = "1" ]; then
uci set $CONFIG.$node.default_node="$new_node"
elif [ "$shunt_logic" = "2" ]; then
uci set $CONFIG.$node.main_node="$new_node"
fi
uci commit $CONFIG
}
new_node=$node
}
run_redir node=$new_node proto=$FLAG bind=0.0.0.0 local_port=$port config_file=$config_file log_file=$log_file
echo $new_node > $TMP_ID_PATH/${FLAG}
[ "$shunt_logic" != "0" ] && [ "$(config_n_get $new_node protocol nil)" = "_shunt" ] && {
echo $(config_n_get $new_node default_node nil) > $TMP_ID_PATH/${FLAG}_default
echo $(config_n_get $new_node main_node nil) > $TMP_ID_PATH/${FLAG}_main
uci commit $CONFIG
}
[ "$flag" = "tcp" ] && {
[ "$(config_t_get global udp_node nil)" = "tcp" ] && [ "$UDP_REDIR_PORT" != "$TCP_REDIR_PORT" ] && {
pgrep -af "$TMP_PATH" | awk 'BEGIN{IGNORECASE=1}/UDP/ && !/acl\/|acl_/{print $1}' | xargs kill -9 >/dev/null 2>&1
UDP_NODE=$new_node
start_redir UDP
}
}
#uci set $CONFIG.@global[0].${flag}_node=$new_node
#uci commit $CONFIG
source $APP_PATH/helper_${DNS_N}.sh logic_restart no_log=1
}
}
start_redir() {
local proto=${1}
eval node=\$${proto}_NODE
@ -1021,12 +971,39 @@ start_socks() {
local http_port=$(config_n_get $id http_port 0)
local http_config_file="HTTP2SOCKS_${id}.json"
run_socks flag=$id node=$node bind=0.0.0.0 socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file
echo $node > $TMP_ID_PATH/SOCKS_${id}
echo $node > $TMP_ID_PATH/socks_${id}
#自动切换逻辑
local enable_autoswitch=$(config_n_get $id enable_autoswitch 0)
[ "$enable_autoswitch" = "1" ] && $APP_PATH/socks_auto_switch.sh ${id} > /dev/null 2>&1 &
done
}
}
}
socks_node_switch() {
local flag new_node
eval_set_val $@
[ -n "$flag" ] && [ -n "$new_node" ] && {
pgrep -af "$TMP_BIN_PATH" | awk -v P1="${flag}" 'BEGIN{IGNORECASE=1}$0~P1 && !/acl\/|acl_/{print $1}' | xargs kill -9 >/dev/null 2>&1
rm -rf $TMP_PATH/SOCKS_${flag}*
rm -rf $TMP_PATH/HTTP2SOCKS_${flag}*
for filename in $(ls ${TMP_SCRIPT_FUNC_PATH}); do
cmd=$(cat ${TMP_SCRIPT_FUNC_PATH}/${filename})
[ -n "$(echo $cmd | grep "${flag}")" ] && rm -f ${TMP_SCRIPT_FUNC_PATH}/${filename}
done
local port=$(config_n_get $flag port)
local config_file="SOCKS_${flag}.json"
local log_file="SOCKS_${flag}.log"
local http_port=$(config_n_get $flag http_port 0)
local http_config_file="HTTP2SOCKS_${flag}.json"
LOG_FILE="/dev/null"
run_socks flag=$flag node=$new_node bind=0.0.0.0 socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file
echo $new_node > $TMP_ID_PATH/socks_${flag}
}
}
clean_log() {
logsnum=$(cat $LOG_FILE 2>/dev/null | wc -l)
[ "$logsnum" -gt 1000 ] && {
@ -1106,9 +1083,6 @@ start_crontab() {
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
start_daemon=$(config_t_get global_delay start_daemon 0)
[ "$start_daemon" = "1" ] && $APP_PATH/monitor.sh > /dev/null 2>&1 &
AUTO_SWITCH_ENABLE=$(config_t_get auto_switch enable 0)
[ "$AUTO_SWITCH_ENABLE" = "1" ] && $APP_PATH/test.sh > /dev/null 2>&1 &
else
echolog "运行于非代理模式,仅允许服务启停的定时任务。"
fi
@ -1599,7 +1573,7 @@ stop() {
[ -s "$TMP_PATH/bridge_nf_ipt" ] && sysctl -w net.bridge.bridge-nf-call-iptables=$(cat $TMP_PATH/bridge_nf_ipt) >/dev/null 2>&1
[ -s "$TMP_PATH/bridge_nf_ip6t" ] && sysctl -w net.bridge.bridge-nf-call-ip6tables=$(cat $TMP_PATH/bridge_nf_ip6t) >/dev/null 2>&1
rm -rf ${TMP_PATH}
rm -rf /tmp/lock/${CONFIG}_script.lock
rm -rf /tmp/lock/${CONFIG}_socks_auto_switch*
echolog "清空并关闭相关程序和缓存完成。"
exit 0
}
@ -1685,8 +1659,8 @@ run_socks)
run_redir)
run_redir $@
;;
node_switch)
node_switch $@
socks_node_switch)
socks_node_switch $@
;;
echolog)
echolog $@

View File

@ -0,0 +1,180 @@
#!/bin/sh
CONFIG=passwall
LOG_FILE=/tmp/log/$CONFIG.log
LOCK_FILE_DIR=/tmp/lock
flag=0
echolog() {
local d="$(date "+%Y-%m-%d %H:%M:%S")"
#echo -e "$d: $1"
echo -e "$d: $1" >> $LOG_FILE
}
config_n_get() {
local ret=$(uci -q get "${CONFIG}.${1}.${2}" 2>/dev/null)
echo "${ret:=$3}"
}
test_url() {
local url=$1
local try=1
[ -n "$2" ] && try=$2
local timeout=2
[ -n "$3" ] && timeout=$3
local extra_params=$4
curl --help all | grep "\-\-retry-all-errors" > /dev/null
[ $? == 0 ] && extra_params="--retry-all-errors ${extra_params}"
status=$(/usr/bin/curl -I -o /dev/null -skL --user-agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36" ${extra_params} --connect-timeout ${timeout} --retry ${try} -w %{http_code} "$url")
case "$status" in
204)
status=200
;;
esac
echo $status
}
test_proxy() {
result=0
status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x socks5h://127.0.0.1:${socks_port}")
if [ "$status" = "200" ]; then
result=0
else
status2=$(test_url "https://www.baidu.com" ${retry_num} ${connect_timeout})
if [ "$status2" = "200" ]; then
result=1
else
result=2
ping -c 3 -W 1 223.5.5.5 > /dev/null 2>&1
[ $? -eq 0 ] && {
result=1
}
fi
fi
echo $result
}
test_node() {
local node_id=$1
local _type=$(echo $(config_n_get ${node_id} type nil) | tr 'A-Z' 'a-z')
[ "${_type}" != "nil" ] && {
local _tmp_port=$(/usr/share/${CONFIG}/app.sh get_new_port 61080 tcp,udp)
/usr/share/${CONFIG}/app.sh run_socks flag="test_node_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=test_node_${node_id}.json
local curlx="socks5h://127.0.0.1:${_tmp_port}"
sleep 1s
_proxy_status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x $curlx")
pgrep -af "test_node_${node_id}" | awk '! /socks_auto_switch\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1
rm -rf "/tmp/etc/${CONFIG}/test_node_${node_id}.json"
if [ "${_proxy_status}" -eq 200 ]; then
return 0
fi
}
return 1
}
test_auto_switch() {
flag=$(expr $flag + 1)
local b_nodes=$1
local now_node=$2
[ -z "$now_node" ] && {
local f="/tmp/etc/$CONFIG/id/socks_${id}"
if [ -f "${f}" ]; then
now_node=$(cat ${f})
else
#echolog "自动切换检测:未知错误"
return 1
fi
}
[ $flag -le 1 ] && {
main_node=$now_node
}
status=$(test_proxy)
if [ "$status" == 2 ]; then
echolog "自动切换检测:无法连接到网络,请检查网络是否正常!"
return 2
fi
#检测主节点是否能使用
if [ "$restore_switch" == "1" ] && [ "$main_node" != "nil" ] && [ "$now_node" != "$main_node" ]; then
test_node ${main_node}
[ $? -eq 0 ] && {
#主节点正常,切换到主节点
echolog "自动切换检测:${id}主节点【$(config_n_get $main_node type)[$(config_n_get $main_node remarks)]】正常,切换到主节点!"
/usr/share/${CONFIG}/app.sh socks_node_switch flag=${id} new_node=${main_node}
[ $? -eq 0 ] && {
echolog "自动切换检测:${id}节点切换完毕!"
}
return 0
}
fi
if [ "$status" == 0 ]; then
#echolog "自动切换检测:${id}【$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】正常。"
return 0
elif [ "$status" == 1 ]; then
echolog "自动切换检测:${id}$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】异常,切换到下一个备用节点检测!"
local new_node
in_backup_nodes=$(echo $b_nodes | grep $now_node)
# 判断当前节点是否存在于备用节点列表里
if [ -z "$in_backup_nodes" ]; then
# 如果不存在,设置第一个节点为新的节点
new_node=$(echo $b_nodes | awk -F ' ' '{print $1}')
else
# 如果存在,设置下一个备用节点为新的节点
#local count=$(expr $(echo $b_nodes | grep -o ' ' | wc -l) + 1)
local next_node=$(echo $b_nodes | awk -F "$now_node" '{print $2}' | awk -F " " '{print $1}')
if [ -z "$next_node" ]; then
new_node=$(echo $b_nodes | awk -F ' ' '{print $1}')
else
new_node=$next_node
fi
fi
test_node ${new_node}
if [ $? -eq 0 ]; then
[ "$restore_switch" == "0" ] && {
uci set $CONFIG.${id}.node=$new_node
[ -z "$(echo $b_nodes | grep $main_node)" ] && uci add_list $CONFIG.${id}.autoswitch_backup_node=$main_node
uci commit $CONFIG
}
echolog "自动切换检测:${id}$(config_n_get $new_node type)[$(config_n_get $new_node remarks)]】正常,切换到此节点!"
/usr/share/${CONFIG}/app.sh socks_node_switch flag=${id} new_node=${new_node}
[ $? -eq 0 ] && {
echolog "自动切换检测:${id}节点切换完毕!"
}
return 0
else
test_auto_switch "${b_nodes}" ${new_node}
fi
fi
}
start() {
id=$1
LOCK_FILE=${LOCK_FILE_DIR}/${CONFIG}_socks_auto_switch_${id}.lock
main_node=$(config_n_get $id node nil)
socks_port=$(config_n_get $id port 0)
delay=$(config_n_get $id autoswitch_testing_time 1)
sleep 5s
connect_timeout=$(config_n_get $id autoswitch_connect_timeout 3)
retry_num=$(config_n_get $id autoswitch_retry_num 1)
restore_switch=$(config_n_get $id autoswitch_restore_switch 0)
probe_url=$(config_n_get $id autoswitch_probe_url "https://www.google.com/generate_204")
backup_node=$(config_n_get $id autoswitch_backup_node nil)
while [ -n "$backup_node" -a "$backup_node" != "nil" ]; do
[ -f "$LOCK_FILE" ] && {
sleep 6s
continue
}
touch $LOCK_FILE
backup_node=$(echo $backup_node | tr -s ' ' '\n' | uniq | tr -s '\n' ' ')
test_auto_switch "$backup_node"
rm -f $LOCK_FILE
sleep ${delay}m
done
}
start $@

View File

@ -173,46 +173,48 @@ do
end)
end
local tcp_node_table = uci:get(appname, "@auto_switch[0]", "tcp_node")
if tcp_node_table then
local nodes = {}
local new_nodes = {}
for k,node_id in ipairs(tcp_node_table) do
if node_id then
local currentNode = uci:get_all(appname, node_id) or nil
if currentNode then
if currentNode.protocol and (currentNode.protocol == "_balancing" or currentNode.protocol == "_shunt") then
currentNode = nil
end
nodes[#nodes + 1] = {
log = true,
remarks = "TCP备用节点的列表[" .. k .. "]",
currentNode = currentNode,
set = function(o, server)
for kk, vv in pairs(CONFIG) do
if (vv.remarks == "TCP备用节点的列表") then
table.insert(vv.new_nodes, server)
uci:foreach(appname, "socks", function(o)
local id = o[".name"]
local node_table = uci:get(appname, id, "autoswitch_backup_node")
if node_table then
local nodes = {}
local new_nodes = {}
for k,node_id in ipairs(node_table) do
if node_id then
local currentNode = uci:get_all(appname, node_id) or nil
if currentNode then
if currentNode.protocol and (currentNode.protocol == "_balancing" or currentNode.protocol == "_shunt") then
currentNode = nil
end
nodes[#nodes + 1] = {
log = true,
remarks = "Socks[" .. id .. "]备用节点的列表[" .. k .. "]",
currentNode = currentNode,
set = function(o, server)
for kk, vv in pairs(CONFIG) do
if (vv.remarks == id .. "备用节点的列表") then
table.insert(vv.new_nodes, server)
end
end
end
end
}
end
end
end
CONFIG[#CONFIG + 1] = {
remarks = "TCP备用节点的列表",
nodes = nodes,
new_nodes = new_nodes,
set = function(o)
for kk, vv in pairs(CONFIG) do
if (vv.remarks == "TCP备用节点的列表") then
--log("刷新自动切换的TCP备用节点的列表")
uci:set_list(appname, "@auto_switch[0]", "tcp_node", vv.new_nodes)
}
end
end
end
}
end
CONFIG[#CONFIG + 1] = {
remarks = id .. "备用节点的列表",
nodes = nodes,
new_nodes = new_nodes,
set = function(o)
for kk, vv in pairs(CONFIG) do
if (vv.remarks == id .. "备用节点的列表") then
uci:set_list(appname, id, "autoswitch_backup_node", vv.new_nodes)
end
end
end
}
end
end)
uci:foreach(appname, "nodes", function(node)
if node.protocol and node.protocol == '_shunt' then

View File

@ -2,8 +2,6 @@
CONFIG=passwall
LOG_FILE=/tmp/log/$CONFIG.log
LOCK_FILE_DIR=/tmp/lock
LOCK_FILE=${LOCK_FILE_DIR}/${CONFIG}_script.lock
echolog() {
local d="$(date "+%Y-%m-%d %H:%M:%S")"
@ -16,13 +14,6 @@ config_n_get() {
echo "${ret:=$3}"
}
config_t_get() {
local index=0
[ -n "$4" ] && index=$4
local ret=$(uci -q get $CONFIG.@$1[$index].$2 2>/dev/null)
echo ${ret:=$3}
}
test_url() {
local url=$1
local try=1
@ -118,147 +109,6 @@ test_node() {
return 1
}
flag=0
main_node=$(config_t_get global tcp_node nil)
test_auto_switch() {
flag=$(expr $flag + 1)
local TYPE=$1
local b_tcp_nodes=$2
local now_node=$3
[ -z "$now_node" ] && {
if [ -f "/tmp/etc/$CONFIG/id/${TYPE}" ]; then
now_node=$(cat /tmp/etc/$CONFIG/id/${TYPE})
if [ "$(config_n_get $now_node protocol nil)" = "_shunt" ]; then
if [ "$shunt_logic" == "1" ] && [ -f "/tmp/etc/$CONFIG/id/${TYPE}_default" ]; then
now_node=$(cat /tmp/etc/$CONFIG/id/${TYPE}_default)
elif [ "$shunt_logic" == "2" ] && [ -f "/tmp/etc/$CONFIG/id/${TYPE}_main" ]; then
now_node=$(cat /tmp/etc/$CONFIG/id/${TYPE}_main)
else
shunt_logic=0
fi
else
shunt_logic=0
fi
else
#echolog "自动切换检测:未知错误"
return 1
fi
}
[ $flag -le 1 ] && {
main_node=$now_node
}
status=$(test_proxy)
if [ "$status" == 2 ]; then
echolog "自动切换检测:无法连接到网络,请检查网络是否正常!"
return 2
fi
#检测主节点是否能使用
if [ "$restore_switch" == "1" ] && [ "$main_node" != "nil" ] && [ "$now_node" != "$main_node" ]; then
test_node ${main_node}
[ $? -eq 0 ] && {
#主节点正常,切换到主节点
echolog "自动切换检测:${TYPE}主节点【$(config_n_get $main_node type)[$(config_n_get $main_node remarks)]】正常,切换到主节点!"
/usr/share/${CONFIG}/app.sh node_switch flag=${TYPE} new_node=${main_node} shunt_logic=${shunt_logic}
[ $? -eq 0 ] && {
echolog "自动切换检测:${TYPE}节点切换完毕!"
[ "$shunt_logic" != "0" ] && {
local tcp_node=$(config_t_get global tcp_node nil)
[ "$(config_n_get $tcp_node protocol nil)" = "_shunt" ] && {
if [ "$shunt_logic" == "1" ]; then
uci set $CONFIG.$tcp_node.default_node="$main_node"
elif [ "$shunt_logic" == "2" ]; then
uci set $CONFIG.$tcp_node.main_node="$main_node"
fi
uci commit $CONFIG
}
}
}
return 0
}
fi
if [ "$status" == 0 ]; then
#echolog "自动切换检测:${TYPE}节点【$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】正常。"
return 0
elif [ "$status" == 1 ]; then
echolog "自动切换检测:${TYPE}节点【$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】异常,切换到下一个备用节点检测!"
local new_node
in_backup_nodes=$(echo $b_tcp_nodes | grep $now_node)
# 判断当前节点是否存在于备用节点列表里
if [ -z "$in_backup_nodes" ]; then
# 如果不存在,设置第一个节点为新的节点
new_node=$(echo $b_tcp_nodes | awk -F ' ' '{print $1}')
else
# 如果存在,设置下一个备用节点为新的节点
#local count=$(expr $(echo $b_tcp_nodes | grep -o ' ' | wc -l) + 1)
local next_node=$(echo $b_tcp_nodes | awk -F "$now_node" '{print $2}' | awk -F " " '{print $1}')
if [ -z "$next_node" ]; then
new_node=$(echo $b_tcp_nodes | awk -F ' ' '{print $1}')
else
new_node=$next_node
fi
fi
test_node ${new_node}
if [ $? -eq 0 ]; then
[ "$restore_switch" == "0" ] && {
[ "$shunt_logic" == "0" ] && uci set $CONFIG.@global[0].tcp_node=$new_node
[ -z "$(echo $b_tcp_nodes | grep $main_node)" ] && uci add_list $CONFIG.@auto_switch[0].tcp_node=$main_node
uci commit $CONFIG
}
echolog "自动切换检测:${TYPE}节点【$(config_n_get $new_node type)[$(config_n_get $new_node remarks)]】正常,切换到此节点!"
/usr/share/${CONFIG}/app.sh node_switch flag=${TYPE} new_node=${new_node} shunt_logic=${shunt_logic}
[ $? -eq 0 ] && {
[ "$restore_switch" == "1" ] && [ "$shunt_logic" != "0" ] && {
local tcp_node=$(config_t_get global tcp_node nil)
[ "$(config_n_get $tcp_node protocol nil)" = "_shunt" ] && {
if [ "$shunt_logic" == "1" ]; then
uci set $CONFIG.$tcp_node.default_node="$main_node"
elif [ "$shunt_logic" == "2" ]; then
uci set $CONFIG.$tcp_node.main_node="$main_node"
fi
uci commit $CONFIG
}
}
echolog "自动切换检测:${TYPE}节点切换完毕!"
}
return 0
else
test_auto_switch ${TYPE} "${b_tcp_nodes}" ${new_node}
fi
fi
}
start() {
ENABLED=$(config_t_get global enabled 0)
[ "$ENABLED" != 1 ] && return 1
ENABLED=$(config_t_get auto_switch enable 0)
[ "$ENABLED" != 1 ] && return 1
delay=$(config_t_get auto_switch testing_time 1)
#sleep 9s
connect_timeout=$(config_t_get auto_switch connect_timeout 3)
retry_num=$(config_t_get auto_switch retry_num 3)
restore_switch=$(config_t_get auto_switch restore_switch 0)
shunt_logic=$(config_t_get auto_switch shunt_logic 0)
while [ "$ENABLED" -eq 1 ]; do
[ -f "$LOCK_FILE" ] && {
sleep 6s
continue
}
touch $LOCK_FILE
TCP_NODE=$(config_t_get auto_switch tcp_node nil)
[ -n "$TCP_NODE" -a "$TCP_NODE" != "nil" ] && {
TCP_NODE=$(echo $TCP_NODE | tr -s ' ' '\n' | uniq | tr -s '\n' ' ')
test_auto_switch TCP "$TCP_NODE"
}
rm -f $LOCK_FILE
sleep ${delay}m
done
}
arg1=$1
shift
case $arg1 in
@ -268,7 +118,4 @@ test_url)
url_test_node)
url_test_node $@
;;
*)
start
;;
esac