🚀 Sync 2026-03-18 20:29:42

This commit is contained in:
github-actions[bot] committed 2026-03-18 20:29:42 +08:00
1 parent c62c96aa04
commit 79996b4e00
212 files changed
+6047 -30308

No files matched your search

@@ -2,50 +2,115 @@ module YAML
class << self
alias_method :load, :unsafe_load if YAML.respond_to? :unsafe_load
alias_method :original_dump, :dump
alias_method :original_load_file, :load_file
end
def self.LOG(info)
puts Time.new.strftime("%Y-%m-%d %H:%M:%S") + " #{info}"
puts Time.new.strftime("%Y-%m-%d %H:%M:%S") + " [Info] " + "#{info}"
end
def self.LOG_ERROR(info)
puts Time.new.strftime("%Y-%m-%d %H:%M:%S") + " [Error] " + "#{info}"
end
def self.LOG_WARN(info)
puts Time.new.strftime("%Y-%m-%d %H:%M:%S") + " [Warning] " + "#{info}"
end
def self.LOG_TIP(info)
puts Time.new.strftime("%Y-%m-%d %H:%M:%S") + " [Tip] " + "#{info}"
end
# Keep `short-id` as string before YAML parsing so leading zeros are preserved.
# This is required for REALITY short-id values like `00000000`.
def self.load_file(filename, *args, **kwargs)
yaml_content = File.read(filename)
processed_content = fix_short_id_quotes(yaml_content)
if kwargs.empty?
load(processed_content, *args)
else
load(processed_content, *args, **kwargs)
end
end
def self.dump(obj, io = nil, **options)
if io.nil?
yaml_content = original_dump(obj, **options)
fix_short_id_quotes(yaml_content)
elsif io.respond_to?(:write)
require 'stringio'
temp_io = StringIO.new
original_dump(obj, temp_io, **options)
yaml_content = temp_io.string
processed_content = fix_short_id_quotes(yaml_content)
io.write(processed_content)
io
else
yaml_content = original_dump(obj, io, **options)
fix_short_id_quotes(yaml_content)
begin
if io.nil?
yaml_content = original_dump(obj, **options)
fix_short_id_quotes(yaml_content)
elsif io.respond_to?(:write)
require 'stringio'
temp_io = StringIO.new
original_dump(obj, temp_io, **options)
yaml_content = temp_io.string
processed_content = fix_short_id_quotes(yaml_content)
io.write(processed_content)
io
else
yaml_content = original_dump(obj, io, **options)
fix_short_id_quotes(yaml_content)
end
rescue => e
LOG_ERROR("Write file failed:【%s】" % [e.message])
nil
end
end
private
SHORT_ID_REGEX = /^(\s*short-id:\s*)([^\s"'\n][^\s,}\n]*)$/m.freeze
QUOTED_VALUE_REGEX = /^["'].*["']$/.freeze
SHORT_ID_REGEX = /^(\s*)short-id:\s*(.*)$/
LIST_ITEM_REGEX = /^(\s*)-\s*(.*)$/
KEY_REGEX = /^(\s*)([a-zA-Z0-9_-]+):\s*(.*)$/
QUOTED_VALUE_REGEX = /^["'].*["']$/
# Inline map support, e.g. reality-opts: { ..., short-id: 00000000 }
INLINE_SHORT_ID_REGEX = /(short-id:\s*)(?!["'\[])([^\s,"'{}\[\]\n\r]+)(?=\s*(?:[,}\]\n\r]|$))/m.freeze
def self.fix_short_id_quotes(yaml_content)
return yaml_content unless yaml_content.include?('short-id:')
yaml_content.lines.map do |line|
if line =~ SHORT_ID_REGEX
field_name = $1
value = $2
if value !~ QUOTED_VALUE_REGEX
"#{field_name}\"#{value}\"\n"
else
"#{field_name}#{value}\n"
end
else
line
begin
# First, normalize inline-map style unquoted short-id.
processed = yaml_content.gsub(INLINE_SHORT_ID_REGEX) do
"#{$1}\"#{$2}\""
end
end.join
lines = processed.lines
short_id_indices = lines.each_index.select { |i| lines[i] =~ SHORT_ID_REGEX }
short_id_indices.each do |short_id_index|
line = lines[short_id_index]
if line =~ SHORT_ID_REGEX
indent = $1
value = $2.strip
if value.empty?
in_short_id = true
(short_id_index + 1...lines.size).each do |i|
line = lines[i]
if line =~ LIST_ITEM_REGEX
if in_short_id
indent = $1
value = $2.strip
if value !~ QUOTED_VALUE_REGEX
lines[i] = "#{indent}- \"#{value}\"\n"
end
end
elsif line =~ KEY_REGEX
in_short_id = false
break
end
end
else
if value !~ QUOTED_VALUE_REGEX
lines[short_id_index] = "#{indent}short-id: \"#{value}\"\n"
end
end
end
end
lines.join
rescue => e
LOG_ERROR("Fix short-id values type failed:【%s】" % [e.message])
yaml_content
end
end
end
end
@@ -1,21 +0,0 @@
#!/bin/sh
. /lib/functions.sh
cfg_unused_servers_del()
{
local section="$1"
config_get_bool "enabled" "$section" "enabled" "1"
if [ "$enabled" = "1" ]; then
return
fi
#删除未选中节点
uci -q delete openclash."$section"
}
config_load "openclash"
config_foreach cfg_unused_servers_del "servers"
uci commit openclash
@@ -14,8 +14,6 @@ del_lock() {
set_lock
TIME=$(date "+%Y-%m-%d-%H")
CHTIME=$(date "+%Y-%m-%d-%H" -r "/tmp/clash_last_version" 2>/dev/null)
DOWNLOAD_FILE="/tmp/clash_last_version"
RELEASE_BRANCH=$(uci_get_config "release_branch" || echo "master")
github_address_mod=$(uci_get_config "github_address_mod" || echo 0)
@@ -23,17 +21,15 @@ if [ -n "$1" ]; then
github_address_mod="$1"
fi
if [ "$TIME" != "$CHTIME" ]; then
if [ "$github_address_mod" != "0" ]; then
if [ "$github_address_mod" == "https://cdn.jsdelivr.net/" ] || [ "$github_address_mod" == "https://fastly.jsdelivr.net/" ] || [ "$github_address_mod" == "https://testingcf.jsdelivr.net/" ]; then
DOWNLOAD_URL="${github_address_mod}gh/vernesong/OpenClash@core/${RELEASE_BRANCH}/core_version"
else
DOWNLOAD_URL="${github_address_mod}https://raw.githubusercontent.com/vernesong/OpenClash/core/${RELEASE_BRANCH}/core_version"
fi
if [ "$github_address_mod" != "0" ]; then
if [ "$github_address_mod" == "https://cdn.jsdelivr.net/" ] || [ "$github_address_mod" == "https://fastly.jsdelivr.net/" ] || [ "$github_address_mod" == "https://testingcf.jsdelivr.net/" ]; then
DOWNLOAD_URL="${github_address_mod}gh/vernesong/OpenClash@core/${RELEASE_BRANCH}/core_version"
else
DOWNLOAD_URL="https://raw.githubusercontent.com/vernesong/OpenClash/core/${RELEASE_BRANCH}/core_version"
DOWNLOAD_URL="${github_address_mod}https://raw.githubusercontent.com/vernesong/OpenClash/core/${RELEASE_BRANCH}/core_version"
fi
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "$DOWNLOAD_FILE"
else
DOWNLOAD_URL="https://raw.githubusercontent.com/vernesong/OpenClash/core/${RELEASE_BRANCH}/core_version"
fi
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "$DOWNLOAD_FILE" "$DOWNLOAD_FILE"
del_lock
@@ -7,20 +7,51 @@ LOG_OUT()
{
if [ -n "${1}" ]; then
echo -e "${1}" > $START_LOG
echo -e "$(date "+%Y-%m-%d %H:%M:%S") ${1}" >> $LOG_FILE
echo -e "$(date "+%Y-%m-%d %H:%M:%S") [Info] ${1}" >> $LOG_FILE
fi
}
LOG_TIP()
{
if [ -n "${1}" ]; then
echo -e "${1}" > $START_LOG
echo -e "$(date "+%Y-%m-%d %H:%M:%S") [Tip] ${1}" >> $LOG_FILE
fi
}
LOG_WARN()
{
if [ -n "${1}" ]; then
echo -e "${1}" > $START_LOG
echo -e "$(date "+%Y-%m-%d %H:%M:%S") [Warning] ${1}" >> $LOG_FILE
fi
}
LOG_ERROR()
{
if [ -n "${1}" ]; then
echo -e "${1}" > $START_LOG
echo -e "$(date "+%Y-%m-%d %H:%M:%S") [Error] ${1}" >> $LOG_FILE
fi
}
LOG_INFO()
{
if [ -n "${1}" ]; then
echo -e "$(date "+%Y-%m-%d %H:%M:%S") ${1}" >> $LOG_FILE
echo -e "$(date "+%Y-%m-%d %H:%M:%S") [Info] ${1}" >> $LOG_FILE
fi
}
LOG_WATCHDOG()
{
if [ -n "${1}" ]; then
echo -e "$(date "+%Y-%m-%d %H:%M:%S") [Watchdog] ${1}" >> $LOG_FILE
fi
}
LOG_ALERT()
{
echo -e "$(tail -n 20 $LOG_FILE |grep -E 'level=fatal|level=error|FTL\ \[Config\]' |awk 'END {print}')" > $START_LOG
echo -e "$(tail -n 20 $LOG_FILE |grep -E 'level=fatal|level=error' |awk 'END {print}')" > $START_LOG
sleep 3
}
@@ -21,10 +21,8 @@ set_lock
LOGTIME=$(echo $(date "+%Y-%m-%d %H:%M:%S"))
LOG_FILE="/tmp/openclash.log"
CFG_FILE="/tmp/yaml_sub_tmp_config.yaml"
CRON_FILE="/etc/crontabs/root"
CONFIG_PATH=$(uci_get_config "config_path")
servers_update=$(uci_get_config "servers_update")
router_self_proxy=$(uci_get_config "router_self_proxy" || echo 1)
FW4=$(command -v fw4)
CLASH="/etc/openclash/clash"
@@ -55,7 +53,7 @@ config_test()
local IFS=$'\n'
for i in $test_info; do
if [ -n "$(echo "$i" |grep "configuration file")" ]; then
local info=$(echo "$i" |sed "s# ${CFG_FILE} #【${CONFIG_FILE}】#g")
local info=$(echo "$i" |sed "s# ${CFG_FILE} #【${name}】#g")
LOG_OUT "$info"
else
echo "$i" >> "$LOG_FILE"
@@ -71,23 +69,19 @@ config_test()
config_download()
{
LOG_OUT "Tip: Config File【$name】Downloading User-Agent【$sub_ua】..."
if [ -n "$subscribe_url_param" ]; then
if [ -n "$c_address" ]; then
LOG_INFO "Tip: Config File【$name】Downloading URL【$c_address$subscribe_url_param】..."
DOWNLOAD_URL="${c_address}${subscribe_url_param}"
DOWNLOAD_PARAM="$sub_ua"
else
LOG_INFO "Tip: Config File【$name】Downloading URL【https://api.dler.io/sub$subscribe_url_param】..."
DOWNLOAD_URL="https://api.dler.io/sub${subscribe_url_param}"
DOWNLOAD_PARAM="$sub_ua"
fi
else
LOG_INFO "Tip: Config File【$name】Downloading URL【$subscribe_url】..."
LOG_TIP "Config File【$name】Downloading User-Agent【$sub_ua】..."
if [ -n "$subscribe_url_param" ] && [ -n "$c_address" ]; then
LOG_INFO "Config File【$name】Downloading URL【$c_address$subscribe_url_param】..."
DOWNLOAD_URL="${c_address}${subscribe_url_param}"
DOWNLOAD_PARAM="$sub_ua"
fi
if [ -z "$DOWNLOAD_URL" ]; then
LOG_INFO "Config File【$name】Downloading URL【$subscribe_url】..."
DOWNLOAD_URL="${subscribe_url}"
DOWNLOAD_PARAM="$sub_ua"
fi
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "$CFG_FILE" "$DOWNLOAD_PARAM"
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "$CFG_FILE" "$CONFIG_FILE" "$DOWNLOAD_PARAM"
DOWNLOAD_RESULT=$?
}
config_cus_up()
@@ -105,11 +99,11 @@ config_cus_up()
fi
if [ -z "$subscribe_url_param" ]; then
if [ -n "$key_match_param" ] || [ -n "$key_ex_match_param" ]; then
LOG_OUT "Config File【$name】is Replaced Successfully, Start Picking Nodes..."
LOG_OUT "Config File【$name】Start Picking Nodes..."
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
begin
threads = [];
Value = YAML.load_file('$CONFIG_FILE');
Value = YAML.load_file('$CFG_FILE');
if Value.has_key?('proxies') and not Value['proxies'].to_a.empty? then
Value['proxies'].reverse.each{
|x|
@@ -164,35 +158,12 @@ config_cus_up()
end;
threads.each(&:join);
rescue Exception => e
YAML.LOG('Error: Filter Proxies Failed,【' + e.message + '】');
YAML.LOG_ERROR('Filter Proxies Failed,【' + e.message + '】');
ensure
File.open('$CONFIG_FILE','w') {|f| YAML.dump(Value, f)};
File.open('$CFG_FILE','w') {|f| YAML.dump(Value, f)};
end" 2>/dev/null >> $LOG_FILE
fi
fi
if [ "$servers_update" -eq 1 ]; then
LOG_OUT "Config File【$name】is Replaced Successfully, Start to Reserving..."
uci -q set openclash.config.config_update_path="/etc/openclash/config/$name.yaml"
uci -q set openclash.config.servers_if_update=1
uci commit openclash
/usr/share/openclash/yml_groups_get.sh
uci -q set openclash.config.servers_if_update=1
uci commit openclash
/usr/share/openclash/yml_groups_set.sh
if [ "$CONFIG_FILE" == "$CONFIG_PATH" ]; then
restart=1
fi
LOG_OUT "Config File【$name】Update Successful!"
SLOG_CLEAN
elif [ "$CONFIG_FILE" == "$CONFIG_PATH" ]; then
LOG_OUT "Config File【$name】Update Successful!"
restart=1
else
LOG_OUT "Config File【$name】Update Successful!"
SLOG_CLEAN
fi
rm -rf /tmp/Proxy_Group 2>/dev/null
}
config_su_check()
@@ -200,60 +171,36 @@ config_su_check()
LOG_OUT "Config File Test Successful, Check If There is Any Update..."
sed -i 's/!<str> /!!str /g' "$CFG_FILE" >/dev/null 2>&1
if [ -f "$CONFIG_FILE" ]; then
cmp -s "$BACKPACK_FILE" "$CFG_FILE"
if [ "$only_download" -eq 0 ]; then
config_cus_up
fi
cmp -s "$CONFIG_FILE" "$CFG_FILE"
if [ "$?" -ne 0 ]; then
LOG_OUT "Config File【$name】Are Updates, Start Replacing..."
cp "$CFG_FILE" "$BACKPACK_FILE"
#保留规则部分
if [ "$servers_update" -eq 1 ] && [ "$only_download" -eq 0 ]; then
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
Value = YAML.load_file('$CONFIG_FILE');
Value_1 = YAML.load_file('$CFG_FILE');
if Value.key?('rules') or Value.key?('script') or Value.key?('rule-providers') then
if Value.key?('rules') then
Value_1['rules'] = Value['rules']
end;
if Value.key?('script') then
Value_1['script'] = Value['script']
end;
if Value.key?('rule-providers') then
Value_1['rule-providers'] = Value['rule-providers']
end;
File.open('$CFG_FILE','w') {|f| YAML.dump(Value_1, f)};
end;
" 2>/dev/null
fi
mv "$CFG_FILE" "$CONFIG_FILE" 2>/dev/null
if [ "$only_download" -eq 0 ]; then
config_cus_up
else
LOG_OUT "Config File【$name】Update Successful!"
SLOG_CLEAN
fi
LOG_OUT "Config File【$name】Update Successful!"
else
LOG_OUT "Config File【$name】No Change, Do Nothing!"
rm -rf "$CFG_FILE"
SLOG_CLEAN
return
fi
else
LOG_OUT "Config File【$name】Download Successful, Start To Create..."
mv "$CFG_FILE" "$CONFIG_FILE" 2>/dev/null
cp "$CONFIG_FILE" "$BACKPACK_FILE"
if [ "$only_download" -eq 0 ]; then
config_cus_up
else
LOG_OUT "Config File【$name】Update Successful!"
SLOG_CLEAN
fi
mv "$CFG_FILE" "$CONFIG_FILE" 2>/dev/null
LOG_OUT "Config File【$name】Update Successful!"
fi
if [ "$CONFIG_FILE" == "$CONFIG_PATH" ]; then
restart=1
fi
}
config_error()
{
LOG_OUT "Error:【$name】Update Error, Please Try Again Later..."
LOG_ERROR "【$name】Update Error, Please Try Again Later..."
rm -rf "$CFG_FILE" 2>/dev/null
SLOG_CLEAN
return 1
}
change_dns()
@@ -274,13 +221,13 @@ config_download_direct()
config_download
if [ "${PIPESTATUS[0]}" -eq 0 ] && [ -s "$CFG_FILE" ]; then
if [ "$DOWNLOAD_RESULT" -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!"
LOG_ERROR "Config File Tested Faild, Please Check The Log Infos!"
change_dns
config_error
return
@@ -289,12 +236,12 @@ config_download_direct()
begin
YAML.load_file('$CFG_FILE');
rescue Exception => e
YAML.LOG('Error: Unable To Parse Config File,【' + e.message + '】');
YAML.LOG_ERROR('Unable To Parse Config File,【' + e.message + '】');
system 'rm -rf ${CFG_FILE} 2>/dev/null'
end
" 2>/dev/null >> $LOG_FILE
if [ $? -ne 0 ]; then
LOG_OUT "Error: Ruby Works Abnormally, Please Check The Ruby Library Depends!"
LOG_ERROR "Ruby Works Abnormally, Please Check The Ruby Library Depends!"
only_download=1
change_dns
config_su_check
@@ -303,13 +250,16 @@ config_download_direct()
change_dns
config_error
elif ! "$(ruby_read "$CFG_FILE" ".key?('proxies')")" && ! "$(ruby_read "$CFG_FILE" ".key?('proxy-providers')")" ; then
LOG_OUT "Error: Updated Config【$name】Has No Proxy Field, Update Exit..."
LOG_ERROR "Updated Config【$name】Has No Proxy Field, Update Exit..."
change_dns
config_error
else
change_dns
config_su_check
fi
elif [ "$DOWNLOAD_RESULT" -eq 2 ]; then
change_dns
LOG_OUT "Config File【$name】No Change, Do Nothing!"
else
change_dns
config_error
@@ -324,24 +274,24 @@ server_key_match()
local key_match key_word
if [ -n "$(echo "$1" |grep "^ \{0,\}$")" ] || [ -n "$(echo "$1" |grep "^\t\{0,\}$")" ]; then
return
return
fi
if [ -n "$(echo "$1" |grep "&")" ]; then
key_word=$(echo "$1" |sed 's/&/ /g')
for k in $key_word
do
if [ -z "$k" ]; then
continue
fi
k="(?=.*$k)"
key_match="$key_match$k"
done
key_match="^($key_match).*"
for k in $key_word
do
if [ -z "$k" ]; then
continue
fi
k="(?=.*$k)"
key_match="$key_match$k"
done
key_match="^($key_match).*"
else
if [ -n "$1" ]; then
key_match="($1)"
fi
if [ -n "$1" ]; then
key_match="($1)"
fi
fi
if [ "$2" = "keyword" ]; then
@@ -376,7 +326,7 @@ sub_info_get()
{
local section="$1" subscribe_url template_path subscribe_url_param template_path_encode key_match_param key_ex_match_param c_address de_ex_keyword sub_ua append_custom_params
config_get_bool "enabled" "$section" "enabled" "1"
config_get "name" "$section" "name" ""
config_get "name" "$section" "name" "config"
config_get "sub_convert" "$section" "sub_convert" ""
config_get "address" "$section" "address" ""
config_get "keyword" "$section" "keyword" ""
@@ -393,6 +343,9 @@ sub_info_get()
config_get "de_ex_keyword" "$section" "de_ex_keyword" ""
config_get "sub_ua" "$section" "sub_ua" "clash.meta"
CONFIG_FILE="/etc/openclash/config/$name.yaml"
CFG_FILE="/tmp/$name.yaml"
if [ "$enabled" -eq 0 ]; then
if [ -n "$2" ]; then
if [ "$2" != "$CONFIG_FILE" ] && [ "$2" != "$name" ]; then
@@ -419,15 +372,6 @@ sub_info_get()
rule_provider=""
fi
if [ -z "$name" ]; then
name="config"
CONFIG_FILE="/etc/openclash/config/config.yaml"
BACKPACK_FILE="/etc/openclash/backup/config.yaml"
else
CONFIG_FILE="/etc/openclash/config/$name.yaml"
BACKPACK_FILE="/etc/openclash/backup/$name.yaml"
fi
if [ -n "$2" ] && [ "$2" != "$CONFIG_FILE" ] && [ "$2" != "$name" ]; then
return
fi
@@ -477,14 +421,13 @@ sub_info_get()
LOG_OUT "Start Updating Config File【$name】..."
config_download
if [ "${PIPESTATUS[0]}" -eq 0 ] && [ -s "$CFG_FILE" ]; then
if [ "$DOWNLOAD_RESULT" -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!"
LOG_OUT "Error: Config File【$name】Subscribed Failed, Trying to Download Without Agent..."
LOG_ERROR "Config File Tested Faild, Please Check The Log Infos!"
LOG_ERROR "Config File【$name】Subscribed Failed, Trying to Download Without Agent..."
config_download_direct
return
fi
@@ -492,25 +435,27 @@ sub_info_get()
begin
YAML.load_file('$CFG_FILE');
rescue Exception => e
YAML.LOG('Error: Unable To Parse Config File,【' + e.message + '】');
YAML.LOG_ERROR('Unable To Parse Config File,【' + e.message + '】');
system 'rm -rf ${CFG_FILE} 2>/dev/null'
end
" 2>/dev/null >> $LOG_FILE
if [ $? -ne 0 ]; then
LOG_OUT "Error: Ruby Works Abnormally, Please Check The Ruby Library Depends!"
LOG_ERROR "Ruby Works Abnormally, Please Check The Ruby Library Depends!"
only_download=1
config_su_check
elif [ ! -f "$CFG_FILE" ]; then
LOG_OUT "Config File Format Validation Failed, Trying To Download Without Agent..."
config_download_direct
elif ! "$(ruby_read "$CFG_FILE" ".key?('proxies')")" && ! "$(ruby_read "$CFG_FILE" ".key?('proxy-providers')")" ; then
LOG_OUT "Error: Updated Config【$name】Has No Proxy Field, Trying To Download Without Agent..."
LOG_ERROR "Updated Config【$name】Has No Proxy Field, Trying To Download Without Agent..."
config_download_direct
else
config_su_check
fi
elif [ "$DOWNLOAD_RESULT" -eq 2 ]; then
LOG_OUT "Config File【$name】No Change, Do Nothing!"
else
LOG_OUT "Error: Config File【$name】Subscribed Failed, Trying to Download Without Agent..."
LOG_ERROR "Config File【$name】Subscribed Failed, Trying to Download Without Agent..."
config_download_direct
fi
}
@@ -518,8 +463,6 @@ sub_info_get()
#分别获取订阅信息进行处理
config_load "openclash"
config_foreach sub_info_get "config_subscribe" "$1"
uci -q delete openclash.config.config_update_path
uci commit openclash
SLOG_CLEAN
dec_job_counter_and_restart "$restart"
del_lock
del_lock
@@ -40,9 +40,9 @@ fi
LOG_OUT "Start Downloading The Chnroute Cidr List..."
if [ -z "$CHNR_CUSTOM_URL" ]; then
DOWNLOAD_FILE_CURL "https://ispip.clang.cn/all_cn.txt" "/tmp/china_ip_route.txt"
DOWNLOAD_FILE_CURL "https://ispip.clang.cn/all_cn.txt" "/tmp/china_ip_route.txt" "$chnr_path"
else
DOWNLOAD_FILE_CURL "$CHNR_CUSTOM_URL" "/tmp/china_ip_route.txt"
DOWNLOAD_FILE_CURL "$CHNR_CUSTOM_URL" "/tmp/china_ip_route.txt" "$chnr_path"
fi
if [ "$?" -eq 0 ]; then
@@ -69,6 +69,8 @@ if [ "$?" -eq 0 ]; then
else
LOG_OUT "Updated Chnroute Cidr List No Change, Do Nothing..."
fi
elif [ "$?" -eq 2 ]; then
LOG_OUT "Updated Chnroute Cidr List No Change, Do Nothing..."
else
LOG_OUT "Chnroute Cidr List Update Error, Please Try Again Later..."
fi
@@ -76,11 +78,12 @@ fi
#ipv6
LOG_OUT "Start Downloading The Chnroute6 Cidr List..."
if [ -z "$CHNR6_CUSTOM_URL" ]; then
DOWNLOAD_FILE_CURL "https://ispip.clang.cn/all_cn_ipv6.txt" "/tmp/china_ip6_route.txt"
DOWNLOAD_FILE_CURL "https://ispip.clang.cn/all_cn_ipv6.txt" "/tmp/china_ip6_route.txt" "$chnr6_path"
else
DOWNLOAD_FILE_CURL "$CHNR6_CUSTOM_URL" "/tmp/china_ip6_route.txt"
DOWNLOAD_FILE_CURL "$CHNR6_CUSTOM_URL" "/tmp/china_ip6_route.txt" "$chnr6_path"
fi
if [ "$?" -eq 0 ]; then
DOWNLOAD_RESULT=$?
if [ "$DOWNLOAD_RESULT" -eq 0 ]; then
LOG_OUT "Chnroute6 Cidr List Download Success, Check Updated..."
#预处理
if [ -n "$FW4" ]; then
@@ -104,6 +107,8 @@ if [ "$?" -eq 0 ]; then
else
LOG_OUT "Updated Chnroute6 Cidr List No Change, Do Nothing..."
fi
elif [ "$DOWNLOAD_RESULT" -eq 2 ]; then
LOG_OUT "Updated Chnroute6 Cidr List No Change, Do Nothing..."
else
LOG_OUT "Chnroute6 Cidr List Update Error, Please Try Again Later..."
fi
@@ -21,7 +21,7 @@ inc_job_counter
restart=0
github_address_mod=$(uci_get_config "github_address_mod" || echo 0)
if [ "$github_address_mod" = "0" ] && [ -z "$(echo $2 2>/dev/null |grep -E 'http|one_key_update')" ] && [ -z "$(echo $3 2>/dev/null |grep 'http')" ]; then
LOG_OUT "Tip: If the download fails, try setting the CDN in Overwrite Settings - General Settings - Github Address Modify Options"
LOG_TIP "If the download fails, try setting the CDN in Overwrite Settings - General Settings - Github Address Modify Options"
fi
if [ -n "$3" ] && [ "$2" = "one_key_update" ]; then
github_address_mod="$3"
@@ -42,12 +42,12 @@ CPU_MODEL=$(uci_get_config "core_version")
RELEASE_BRANCH=$(uci_get_config "release_branch" || echo "master")
if [ "$github_address_mod" != "0" ]; then
[ ! -f "/tmp/clash_last_version" ] && /usr/share/openclash/clash_version.sh "$github_address_mod" 2>/dev/null
/usr/share/openclash/clash_version.sh "$github_address_mod" 2>/dev/null
else
[ ! -f "/tmp/clash_last_version" ] && /usr/share/openclash/clash_version.sh 2>/dev/null
/usr/share/openclash/clash_version.sh 2>/dev/null
fi
if [ ! -f "/tmp/clash_last_version" ]; then
LOG_OUT "Error: 【"$CORE_TYPE"】Core Version Check Error, Please Try Again Later..."
LOG_ERROR "【"$CORE_TYPE"】Core Version Check Error, Please Try Again Later..."
SLOG_CLEAN
del_lock
exit 0
@@ -78,7 +78,7 @@ fi
if [ "$CORE_CV" != "$CORE_LV" ] || [ -z "$CORE_CV" ]; then
if [ "$CPU_MODEL" != 0 ]; then
LOG_OUT "Tip:【$CORE_TYPE】Core Downloading, Please Try to Download and Upload Manually If Fails"
LOG_TIP "【$CORE_TYPE】Core Downloading, Please Try to Download and Upload Manually If Fails"
if [ "$github_address_mod" != "0" ]; then
if [ "$github_address_mod" == "https://cdn.jsdelivr.net/" ] || [ "$github_address_mod" == "https://fastly.jsdelivr.net/" ] || [ "$github_address_mod" == "https://testingcf.jsdelivr.net/" ]; then
DOWNLOAD_URL="${github_address_mod}gh/vernesong/OpenClash@core/${CORE_URL_PATH}/clash-${CPU_MODEL}.tar.gz"
@@ -97,14 +97,14 @@ if [ "$CORE_CV" != "$CORE_LV" ] || [ -z "$CORE_CV" ]; then
rm -rf "$DOWNLOAD_FILE" "$TMP_FILE" >/dev/null 2>&1
SHOW_DOWNLOAD_PROGRESS=1 DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "$DOWNLOAD_FILE"
download_result=$?
SHOW_DOWNLOAD_PROGRESS=1 DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "$DOWNLOAD_FILE" "$TARGET_CORE_PATH"
DOWNLOAD_RESULT=$?
if [ "$download_result" -eq 0 ]; then
if [ "$DOWNLOAD_RESULT" -eq 0 ]; then
gzip -t "$DOWNLOAD_FILE" >/dev/null 2>&1
if [ "$?" -eq 0 ]; then
LOG_OUT "Tip:【"$CORE_TYPE"】Core Download Successful, Start Update..."
LOG_TIP "【"$CORE_TYPE"】Core Download Successful, Start Update..."
extract_success=true
[ -s "$DOWNLOAD_FILE" ] && {
tar zxvfo "$DOWNLOAD_FILE" -C /tmp >/dev/null 2>&1 || extract_success=false
@@ -116,12 +116,12 @@ if [ "$CORE_CV" != "$CORE_LV" ] || [ -z "$CORE_CV" ]; then
if [ "$extract_success" != "true" ]; then
if [ "$retry_count" -lt "$max_retries" ]; then
LOG_OUT "Error:【$retry_count/$max_retries】【"$CORE_TYPE"】Core Update Failed..."
LOG_ERROR "【$retry_count/$max_retries】【"$CORE_TYPE"】Core Update Failed..."
rm -rf "$TMP_FILE" >/dev/null 2>&1
sleep 2
continue
else
LOG_OUT "Error:【"$CORE_TYPE"】Core Update Failed, Please Make Sure Enough Flash Memory Space or Selected Correct Core Platform And Try Again!"
LOG_ERROR "【"$CORE_TYPE"】Core Update Failed, Please Make Sure Enough Flash Memory Space or Selected Correct Core Platform And Try Again!"
rm -rf "$TMP_FILE" >/dev/null 2>&1
SLOG_CLEAN
del_lock
@@ -132,50 +132,53 @@ if [ "$CORE_CV" != "$CORE_LV" ] || [ -z "$CORE_CV" ]; then
mv "$TMP_FILE" "$TARGET_CORE_PATH" >/dev/null 2>&1
if [ "$?" == "0" ]; then
LOG_OUT "Tip:【"$CORE_TYPE"】Core Update Successful!"
LOG_TIP "【"$CORE_TYPE"】Core Update Successful!"
SLOG_CLEAN
restart=1
break
else
if [ "$retry_count" -lt "$max_retries" ]; then
LOG_OUT "Error:【$retry_count/$max_retries】【"$CORE_TYPE"】Core Update Failed..."
LOG_ERROR "【$retry_count/$max_retries】【"$CORE_TYPE"】Core Update Failed..."
sleep 2
continue
else
LOG_OUT "Error:【"$CORE_TYPE"】Core Update Failed, Please Make Sure Enough Flash Memory Space And Try Again!"
LOG_ERROR "【"$CORE_TYPE"】Core Update Failed, Please Make Sure Enough Flash Memory Space And Try Again!"
SLOG_CLEAN
break
fi
fi
else
if [ "$retry_count" -lt "$max_retries" ]; then
LOG_OUT "Error:【$retry_count/$max_retries】【"$CORE_TYPE"】Core Update Failed..."
LOG_ERROR "【$retry_count/$max_retries】【"$CORE_TYPE"】Core Update Failed..."
sleep 2
continue
else
LOG_OUT "Error:【"$CORE_TYPE"】Core Update Failed, Please Check The Network or Try Again Later!"
LOG_ERROR "【"$CORE_TYPE"】Core Update Failed, Please Check The Network or Try Again Later!"
SLOG_CLEAN
break
fi
fi
elif [ "$DOWNLOAD_RESULT" -eq 2 ]; then
LOG_TIP "【"$CORE_TYPE"】Core Has Not Been Updated, Stop Continuing Operation!"
SLOG_CLEAN
else
if [ "$retry_count" -lt "$max_retries" ]; then
LOG_OUT "Error:【$retry_count/$max_retries】【"$CORE_TYPE"】Core Download Failed..."
LOG_ERROR "【$retry_count/$max_retries】【"$CORE_TYPE"】Core Download Failed..."
sleep 2
continue
else
LOG_OUT "Error:【"$CORE_TYPE"】Core Download Failed, Please Check The Network or Try Again Later!"
LOG_ERROR "【"$CORE_TYPE"】Core Download Failed, Please Check The Network or Try Again Later!"
SLOG_CLEAN
break
fi
fi
done
else
LOG_OUT "Warning: No Compiled Version Selected, Please Select In Update Page And Try Again!"
LOG_WARN "No Compiled Version Selected, Please Select In Update Page And Try Again!"
SLOG_CLEAN
fi
else
LOG_OUT "Tip:【"$CORE_TYPE"】Core Has Not Been Updated, Stop Continuing Operation!"
LOG_TIP "【"$CORE_TYPE"】Core Has Not Been Updated, Stop Continuing Operation!"
SLOG_CLEAN
fi
@@ -1,13 +1,26 @@
#!/bin/bash
. /usr/share/openclash/log.sh
. /usr/share/openclash/openclash_etag.sh
DOWNLOAD_FILE_CURL() {
[ -z "$1" ] || [ -z "$2" ] && return 1
DOWNLOAD_URL=$1
DOWNLOAD_PATH=$2
DOWNLOAD_UA=$3
FILE_PATH=$3
DOWNLOAD_UA=$4
[ -z "$DOWNLOAD_UA" ] && DOWNLOAD_UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
CURL_OUTPUT=$(curl -sLI --connect-timeout 5 -m 10 --speed-time 5 --speed-limit 1 --retry 2 \
-H "User-Agent: ${DOWNLOAD_UA}" "$DOWNLOAD_URL" 2>&1)
NEW_ETAG=$(echo "$CURL_OUTPUT" | grep -i "^etag:" | cut -d' ' -f2- | tr -d '\r\n' | sed 's/^"//;s/"$//')
HTTP_CODE=$(echo "$CURL_OUTPUT" | grep -i "^HTTP" | tail -1 | cut -d' ' -f2)
CACHED_ETAG=$(GET_ETAG_BY_PATH "$FILE_PATH")
if [ "$HTTP_CODE" = "200" ] && [ -n "$NEW_ETAG" ] && [ "$NEW_ETAG" = "$CACHED_ETAG" ] && [ -e "$FILE_PATH" ]; then
return 2
fi
if [ "$SHOW_DOWNLOAD_PROGRESS" = "1" ] || [ "$SHOW_DOWNLOAD_PROGRESS" = "true" ]; then
TEMP_LOG="/tmp/curl_log_$$"
@@ -58,8 +71,6 @@ DOWNLOAD_FILE_CURL() {
rm -rf $DOWNLOAD_PATH
SLOG_CLEAN
return 1
else
return 0
fi
else
CURL_OUTPUT=$(curl -w "\n%{http_code}" -SsL --connect-timeout 30 -m 60 --speed-time 30 --speed-limit 1 --retry 2 -H "User-Agent: ${DOWNLOAD_UA}" "$DOWNLOAD_URL" -o "$DOWNLOAD_PATH" 2>&1)
@@ -72,8 +83,12 @@ DOWNLOAD_FILE_CURL() {
rm -rf $DOWNLOAD_PATH
SLOG_CLEAN
return 1
else
return 0
fi
fi
if [ -n "$NEW_ETAG" ] && [ "$HTTP_CODE" = "200" ]; then
SAVE_ETAG_TO_CACHE "$DOWNLOAD_URL" "$NEW_ETAG" "$FILE_PATH"
fi
return 0
}
@@ -26,8 +26,8 @@ set_lock
DEBUG_LOG="/tmp/openclash_debug.log"
LOGTIME=$(echo $(date "+%Y-%m-%d %H:%M:%S"))
log_level=$(uci_get_config "log_level")
enable_custom_dns=$(uci_get_config "enable_custom_dns")
rule_source=$(uci_get_config "rule_source")
enable_custom_clash_rules=$(uci_get_config "enable_custom_clash_rules")
ipv6_enable=$(uci_get_config "ipv6_enable")
ipv6_dns=$(uci_get_config "ipv6_dns")
@@ -47,8 +47,6 @@ elif [ -x "/usr/bin/apk" ]; then
cpu_model=$(apk list libc 2>/dev/null|awk '{print $2}')
fi
core_meta_version=$(/etc/openclash/core/clash_meta -v 2>/dev/null |awk -F ' ' '{print $3}' |head -1 2>/dev/null)
servers_update=$(uci_get_config "servers_update")
mix_proxies=$(uci_get_config "mix_proxies")
op_version=$(ipk_v "luci-app-openclash")
china_ip_route=$(uci_get_config "china_ip_route")
common_ports=$(uci_get_config "common_ports")
@@ -239,15 +237,6 @@ IPV6-DNS解析: $(ts_cf "$ipv6_dns")
绕过中国大陆IP: $(ts_cf "$china_ip_route")
路由本机代理: $(ts_cf "$router_self_proxy")
#启动异常时建议关闭此项后重试
混合节点: $(ts_cf "$mix_proxies")
保留配置: $(ts_cf "$servers_update")
EOF
cat >> "$DEBUG_LOG" <<-EOF
#启动异常时建议关闭此项后重试
第三方规则: $(ts_cf "$rule_source")
EOF
cat >> "$DEBUG_LOG" <<-EOF
@@ -381,6 +370,9 @@ echo "" >> "$DEBUG_LOG"
echo "#ip route list" >> "$DEBUG_LOG"
ip route list >> "$DEBUG_LOG" 2>/dev/null
echo "" >> "$DEBUG_LOG"
echo "#ip route list table 354" >> "$DEBUG_LOG"
ip route list table 354 >> "$DEBUG_LOG" 2>/dev/null
echo "" >> "$DEBUG_LOG"
echo "#ip rule show" >> "$DEBUG_LOG"
ip rule show >> "$DEBUG_LOG" 2>/dev/null
echo "" >> "$DEBUG_LOG"
@@ -392,6 +384,9 @@ echo "" >> "$DEBUG_LOG"
echo "#ip -6 route list" >> "$DEBUG_LOG"
ip -6 route list >> "$DEBUG_LOG" 2>/dev/null
echo "" >> "$DEBUG_LOG"
echo "#ip -6 route list table 354" >> "$DEBUG_LOG"
ip -6 route list table 354 >> "$DEBUG_LOG" 2>/dev/null
echo "" >> "$DEBUG_LOG"
echo "#ip -6 rule show" >> "$DEBUG_LOG"
ip -6 rule show >> "$DEBUG_LOG" 2>/dev/null
@@ -469,23 +464,23 @@ fi
cat >> "$DEBUG_LOG" <<-EOF
#===================== 最近运行日志(自动切换为Debug模式) =====================#
#===================== 最近运行日志 (切换为Debug模式) =====================#
EOF
if pidof clash >/dev/null; then
curl -SsL -m 3 -H "Content-Type: application/json" -H "Authorization: Bearer ${da_password}" -XPATCH http://${lan_ip}:${cn_port}/configs -d '{"log-level": "debug"}' >/dev/null
if pidof clash >/dev/null && [ "$log_level" != "debug" ]; then
curl -SsL -m 3 --retry 2 -H "Content-Type: application/json" -H "Authorization: Bearer ${da_password}" -XPATCH http://${lan_ip}:${cn_port}/configs -d '{"log-level": "debug"}' >/dev/null
sleep 10
fi
tail -n 100 "/tmp/openclash.log" >> "$DEBUG_LOG" 2>/dev/null
cat >> "$DEBUG_LOG" <<-EOF
#===================== 最近运行日志获取完成(自动切换为silent模式) =====================#
#===================== 最近运行日志获取完成 =====================#
EOF
if pidof clash >/dev/null; then
curl -SsL -m 3 -H "Content-Type: application/json" -H "Authorization: Bearer ${da_password}" -XPATCH http://${lan_ip}:${cn_port}/configs -d '{"log-level": "silent"}' >/dev/null
if pidof clash >/dev/null && [ "$log_level" != "debug" ]; then
curl -SsL -m 3 --retry 2 -H "Content-Type: application/json" -H "Authorization: Bearer ${da_password}" -XPATCH http://${lan_ip}:${cn_port}/configs -d '{"log-level": "'"$log_level"'"}' >/dev/null
fi
cat >> "$DEBUG_LOG" <<-EOF
@@ -1,49 +0,0 @@
#!/usr/bin/lua
require "nixio"
require "luci.util"
require "luci.sys"
local uci = require("luci.model.uci").cursor()
local fs = require "luci.openclash"
local json = require "luci.jsonc"
local function dler_checkin()
local info, path, checkin
local token = fs.uci_get_config("config", "dler_token")
local enable = fs.uci_get_config("config", "dler_checkin") or 0
local interval = fs.uci_get_config("config", "dler_checkin_interval") or 1
local multiple = fs.uci_get_config("config", "dler_checkin_multiple") or 1
path = "/tmp/dler_checkin"
if token and enable == "1" then
checkin = string.format("curl -sL -H 'Content-Type: application/json' -d '{\"access_token\":\"%s\", \"multiple\":\"%s\"}' -X POST https://dler.cloud/api/v1/checkin -o %s", token, multiple, path)
if fs.readfile(path) == "" or not fs.readfile(path) then
luci.sys.exec(checkin)
else
if (os.time() - fs.mtime(path) > interval*3600+1) then
fs.unlink(path)
luci.sys.exec(checkin)
else
os.exit(0)
end
end
if fs.readfile(path) == "" or not fs.readfile(path) then
fs.writefile(path, " ")
end
info = fs.readfile(path)
if info then
info = json.parse(info)
end
if info and info.ret == 200 then
luci.sys.exec(string.format('echo "%s Dler Cloud Checkin Successful, Result:【%s】" >> /tmp/openclash.log', os.date("%Y-%m-%d %H:%M:%S"), info.data.checkin))
else
if info and info.msg then
luci.sys.exec(string.format('echo "%s Dler Cloud Checkin Failed, Result:【%s】" >> /tmp/openclash.log', os.date("%Y-%m-%d %H:%M:%S"), info.msg))
else
luci.sys.exec(string.format('echo "%s Dler Cloud Checkin Failed! Please Check And Try Again..." >> /tmp/openclash.log', os.date("%Y-%m-%d %H:%M:%S")))
end
end
end
os.exit(0)
end
dler_checkin()
@@ -53,9 +53,10 @@
FILE_PATH_INCLUDE="metacubexd-gh-pages"
fi
DOWNLOAD_FILE_CURL "$DOWNLOAD_PATH" "$DASH_FILE_DIR"
DOWNLOAD_FILE_CURL "$DOWNLOAD_PATH" "$DASH_FILE_DIR" "$UNPACK_FILE_DIR"
DOWNLOAD_RESULT=$?
if [ "$?" -eq 0 ] && [ -s "$DASH_FILE_DIR" ]; then
if [ "$DOWNLOAD_RESULT" -eq 0 ] && [ -s "$DASH_FILE_DIR" ]; then
unzip -qt "$DASH_FILE_DIR" >/dev/null 2>&1
if [ "$?" -eq "0" ]; then
cp -rf "$UNPACK_FILE_DIR". "$BACKUP_FILE_DIR" >/dev/null 2>&1
@@ -68,7 +69,7 @@
rm -rf "$DASH_FILE_TMP" >/dev/null 2>&1
LOG_OUT "Control Panel【$DASH_NAME - $DASH_TYPE】Download Successful!" && SLOG_CLEAN
del_lock
exit 1
exit 0
else
LOG_OUT "Control Panel【$DASH_NAME - $DASH_TYPE】Unzip Error!" && SLOG_CLEAN
cp -rf "$BACKUP_FILE_DIR". "$UNPACK_FILE_DIR" >/dev/null 2>&1
@@ -87,6 +88,10 @@
del_lock
exit 2
fi
elif [ "$DOWNLOAD_RESULT" -eq 2 ]; then
LOG_OUT "Control Panel【$DASH_NAME - $DASH_TYPE】Download Successful!" && SLOG_CLEAN
del_lock
exit 0
else
cp -rf "$BACKUP_FILE_DIR". "$UNPACK_FILE_DIR" >/dev/null 2>&1
rm -rf "$BACKUP_FILE_DIR" >/dev/null 2>&1
@@ -94,7 +99,7 @@
rm -rf "$DASH_FILE_TMP" >/dev/null 2>&1
LOG_OUT "Control Panel【$DASH_NAME - $DASH_TYPE】Download Error!" && SLOG_CLEAN
del_lock
exit 0
exit 1
fi
del_lock
@@ -1,105 +0,0 @@
#!/bin/bash
. /usr/share/openclash/log.sh
. /lib/functions.sh
. /usr/share/openclash/openclash_curl.sh
. /usr/share/openclash/uci.sh
urlencode() {
if [ "$#" -eq 1 ]; then
echo "$(/usr/share/openclash/openclash_urlencode.lua "$1")"
fi
}
set_lock() {
exec 870>"/tmp/lock/openclash_rulelist.lock" 2>/dev/null
flock -x 870 2>/dev/null
}
del_lock() {
flock -u 870 2>/dev/null
rm -rf "/tmp/lock/openclash_rulelist.lock" 2>/dev/null
}
set_lock
RULE_FILE_NAME="$1"
RELEASE_BRANCH=$(uci_get_config "release_branch" || echo "master")
github_address_mod=$(uci_get_config "github_address_mod" || echo 0)
if [ -z "$(grep "$RULE_FILE_NAME" /usr/share/openclash/res/rule_providers.list 2>/dev/null)" ]; then
DOWNLOAD_PATH=$(grep -F "$RULE_FILE_NAME" /usr/share/openclash/res/game_rules.list |awk -F ',' '{print $2}' 2>/dev/null)
RULE_FILE_DIR="/etc/openclash/game_rules/$RULE_FILE_NAME"
RULE_TYPE="game"
else
DOWNLOAD_PATH=$(echo "$RULE_FILE_NAME" |awk -F ',' '{print $1$2}' 2>/dev/null)
RULE_FILE_NAME=$(grep -F "$RULE_FILE_NAME" /usr/share/openclash/res/rule_providers.list |awk -F ',' '{print $NF}' 2>/dev/null)
RULE_FILE_DIR="/etc/openclash/rule_provider/$RULE_FILE_NAME"
RULE_TYPE="provider"
fi
if [ -z "$DOWNLOAD_PATH" ]; then
LOG_OUT "Rule File【$RULE_FILE_NAME】Download Error!" && SLOG_CLEAN
del_lock
exit 0
fi
TMP_RULE_DIR="/tmp/$RULE_FILE_NAME"
TMP_RULE_DIR_TMP="/tmp/$RULE_FILE_NAME.tmp"
DOWNLOAD_PATH=$(urlencode "$DOWNLOAD_PATH")
if [ "$RULE_TYPE" = "game" ]; then
if [ "$github_address_mod" != "0" ]; then
if [ "$github_address_mod" == "https://cdn.jsdelivr.net/" ] || [ "$github_address_mod" == "https://fastly.jsdelivr.net/" ] || [ "$github_address_mod" == "https://testingcf.jsdelivr.net/" ]; then
DOWNLOAD_URL="${github_address_mod}gh/FQrabbit/SSTap-Rule@master/rules/${DOWNLOAD_PATH}"
else
DOWNLOAD_URL="${github_address_mod}https://raw.githubusercontent.com/FQrabbit/SSTap-Rule/master/rules/${DOWNLOAD_PATH}"
fi
else
DOWNLOAD_URL="https://raw.githubusercontent.com/FQrabbit/SSTap-Rule/master/rules/${DOWNLOAD_PATH}"
fi
elif [ "$RULE_TYPE" = "provider" ]; then
if [ "$github_address_mod" != "0" ]; then
if [ "$github_address_mod" == "https://cdn.jsdelivr.net/" ] || [ "$github_address_mod" == "https://fastly.jsdelivr.net/" ] || [ "$github_address_mod" == "https://testingcf.jsdelivr.net/" ]; then
DOWNLOAD_URL="${github_address_modgh}/$(echo ${DOWNLOAD_PATH} |awk -F '/master' '{print $1}' 2>/dev/null)@master$(echo ${DOWNLOAD_PATH} |awk -F 'master' '{print $2}')"
else
DOWNLOAD_URL="${github_address_mod}https://raw.githubusercontent.com/${DOWNLOAD_PATH}"
fi
else
DOWNLOAD_URL="https://raw.githubusercontent.com/${DOWNLOAD_PATH}"
fi
fi
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "$TMP_RULE_DIR"
if [ "$?" -eq 0 ] && [ -s "$TMP_RULE_DIR" ]; then
if [ "$RULE_TYPE" = "game" ]; then
cat "$TMP_RULE_DIR" |sed '/^#/d' 2>/dev/null |sed '/^ *$/d' 2>/dev/null |awk '{print " - "$0}' > "$TMP_RULE_DIR_TMP" 2>/dev/null
sed -i '1i\payload:' "$TMP_RULE_DIR_TMP" 2>/dev/null
cmp -s "$TMP_RULE_DIR_TMP" "$RULE_FILE_DIR"
else
cmp -s "$TMP_RULE_DIR" "$RULE_FILE_DIR"
fi
if [ "$?" -ne "0" ]; then
if [ "$RULE_TYPE" = "game" ]; then
mv "$TMP_RULE_DIR_TMP" "$RULE_FILE_DIR" >/dev/null 2>&1
else
mv "$TMP_RULE_DIR" "$RULE_FILE_DIR" >/dev/null 2>&1
fi
rm -rf "$TMP_RULE_DIR" >/dev/null 2>&1
LOG_OUT "Rule File【$RULE_FILE_NAME】Download Successful!" && SLOG_CLEAN
del_lock
exit 1
else
LOG_OUT "Rule File【$RULE_FILE_NAME】No Change, Do Nothing!" && SLOG_CLEAN
rm -rf "$TMP_RULE_DIR" >/dev/null 2>&1
rm -rf "$TMP_RULE_DIR_TMP" >/dev/null 2>&1
del_lock
exit 2
fi
else
rm -rf "$TMP_RULE_DIR" >/dev/null 2>&1
LOG_OUT "Rule File【$RULE_FILE_NAME】Download Error!" && SLOG_CLEAN
del_lock
exit 0
fi
del_lock
@@ -0,0 +1,93 @@
#!/bin/sh
# ETag Cache Management Library
ETAG_CACHE="/etc/openclash/history/etag"
# 根据 path 读取时间戳
GET_ETAG_TIMESTAMP_BY_PATH() {
local path=$1
[ ! -f "$ETAG_CACHE" ] && return 1
local path_hash=$(echo -n "$path" | md5sum | cut -d' ' -f1)
awk -v hash="$path_hash" '
$0 ~ "^\\[" hash "\\]" { found=1; next }
/^\[/ { found=0 }
found && /^time=/ { print $0; exit }
' "$ETAG_CACHE" | cut -d'=' -f2- | sed 's/^"//;s/"$//'
}
# 根据 path 读取 ETag
GET_ETAG_BY_PATH() {
local path=$1
[ ! -f "$ETAG_CACHE" ] && return 1
local path_hash=$(echo -n "$path" | md5sum | cut -d' ' -f1)
awk -v hash="$path_hash" '
$0 ~ "^\\[" hash "\\]" { found=1; next }
/^\[/ { found=0 }
found && /^etag=/ { print $0; exit }
' "$ETAG_CACHE" | cut -d'=' -f2- | sed 's/^"//;s/"$//'
}
# 保存或更新 ETag
SAVE_ETAG_TO_CACHE() {
local url="\"$1\""
local etag="\"$2\""
local path="\"$3\""
local time="\"$(date '+%Y-%m-%d %H:%M:%S')\""
local path_hash=$(echo -n "$3" | md5sum | cut -d' ' -f1)
mkdir -p "$(dirname "$ETAG_CACHE")"
[ ! -f "$ETAG_CACHE" ] && echo "# ETag Cache File" > "$ETAG_CACHE"
if grep -q "^\[$path_hash\]" "$ETAG_CACHE"; then
local temp_file="${ETAG_CACHE}.tmp"
awk -v hash="$path_hash" \
-v new_url="$url" \
-v new_etag="$etag" \
-v new_path="$path" \
-v new_time="$time" '
$0 ~ "^\\[" hash "\\]" {
print;
found=1;
next
}
/^\[/ { found=0 }
found && /^url=/ {
print "url=" new_url;
next
}
found && /^path=/ {
print "path=" new_path;
next
}
found && /^etag=/ {
print "etag=" new_etag;
next
}
found && /^time=/ {
print "time=" new_time;
next
}
{ print }
' "$ETAG_CACHE" > "$temp_file" && mv "$temp_file" "$ETAG_CACHE"
else
cat >> "$ETAG_CACHE" << EOF
[$path_hash]
url=$url
path=$path
etag=$etag
time=$time
EOF
fi
}
# 列出所有缓存
LIST_ETAG_CACHE() {
[ ! -f "$ETAG_CACHE" ] && return 1
cat "$ETAG_CACHE"
}
@@ -43,8 +43,9 @@ if [ -z "$GEOASN_CUSTOM_URL" ]; then
else
DOWNLOAD_URL=$GEOASN_CUSTOM_URL
fi
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "/tmp/GeoLite2-ASN.mmdb"
if [ "$?" -eq 0 ] && [ -s "/tmp/GeoLite2-ASN.mmdb" ]; then
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "/tmp/GeoLite2-ASN.mmdb" "$geoasn_path"
DOWNLOAD_RESULT=$?
if [ "$DOWNLOAD_RESULT" -eq 0 ] && [ -s "/tmp/GeoLite2-ASN.mmdb" ]; then
LOG_OUT "Geo ASN Database Download Success, Check Updated..."
cmp -s /tmp/GeoLite2-ASN.mmdb "$geoasn_path"
if [ "$?" -ne "0" ]; then
@@ -56,6 +57,8 @@ if [ "$?" -eq 0 ] && [ -s "/tmp/GeoLite2-ASN.mmdb" ]; then
else
LOG_OUT "Updated Geo ASN Database No Change, Do Nothing..."
fi
elif [ "$DOWNLOAD_RESULT" -eq 2 ]; then
LOG_OUT "Updated Geo ASN Database No Change, Do Nothing..."
else
LOG_OUT "Geo ASN Database Update Error, Please Try Again Later..."
fi
@@ -43,8 +43,9 @@ if [ -z "$GEOIP_CUSTOM_URL" ]; then
else
DOWNLOAD_URL=$GEOIP_CUSTOM_URL
fi
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "/tmp/GeoIP.dat"
if [ "$?" -eq 0 ] && [ -s "/tmp/GeoIP.dat" ]; then
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "/tmp/GeoIP.dat" "$geoip_path"
DOWNLOAD_RESULT=$?
if [ "$DOWNLOAD_RESULT" -eq 0 ] && [ -s "/tmp/GeoIP.dat" ]; then
LOG_OUT "GeoIP Dat Download Success, Check Updated..."
cmp -s /tmp/GeoIP.dat "$geoip_path"
if [ "$?" -ne "0" ]; then
@@ -56,6 +57,8 @@ if [ "$?" -eq 0 ] && [ -s "/tmp/GeoIP.dat" ]; then
else
LOG_OUT "Updated GeoIP Dat No Change, Do Nothing..."
fi
elif [ "$DOWNLOAD_RESULT" -eq 2 ]; then
LOG_OUT "Updated GeoIP Dat No Change, Do Nothing..."
else
LOG_OUT "GeoIP Dat Update Error, Please Try Again Later..."
fi
@@ -43,8 +43,9 @@ if [ -z "$GEOSITE_CUSTOM_URL" ]; then
else
DOWNLOAD_URL=$GEOSITE_CUSTOM_URL
fi
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "/tmp/GeoSite.dat"
if [ "$?" -eq 0 ] && [ -s "/tmp/GeoSite.dat" ]; then
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "/tmp/GeoSite.dat" "$geosite_path"
DOWNLOAD_RESULT=$?
if [ "$DOWNLOAD_RESULT" -eq 0 ] && [ -s "/tmp/GeoSite.dat" ]; then
LOG_OUT "GeoSite Database Download Success, Check Updated..."
cmp -s /tmp/GeoSite.dat "$geosite_path"
if [ "$?" -ne "0" ]; then
@@ -56,6 +57,8 @@ if [ "$?" -eq 0 ] && [ -s "/tmp/GeoSite.dat" ]; then
else
LOG_OUT "Updated GeoSite Database No Change, Do Nothing..."
fi
elif [ "$DOWNLOAD_RESULT" -eq 2 ]; then
LOG_OUT "Updated GeoSite Database No Change, Do Nothing..."
else
LOG_OUT "GeoSite Database Update Error, Please Try Again Later..."
fi
@@ -51,7 +51,7 @@ fi
if [ -n "$(pidof clash)" ] && [ -f "$CONFIG_FILE" ]; then
if [ "$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)" ] || [ -n "$(apk list libc 2>/dev/null |grep mips)" ]; then
CACHE_PATH="/tmp/etc/openclash/cache.db"
CACHE_PATH="/tmp/etc/openclash/cache.db"
if [ -f "$CACHE_PATH" ]; then
cmp -s "$CACHE_PATH" "$HISTORY_PATH"
if [ "$?" -ne "0" ]; then
@@ -43,8 +43,9 @@ if [ -z "$GEOIP_CUSTOM_URL" ]; then
else
DOWNLOAD_URL=$GEOIP_CUSTOM_URL
fi
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "/tmp/Country.mmdb"
if [ "$?" -eq 0 ] && [ -s "/tmp/Country.mmdb" ]; then
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "/tmp/Country.mmdb" "$geoip_path"
DOWNLOAD_RESULT=$?
if [ "$DOWNLOAD_RESULT" -eq 0 ] && [ -s "/tmp/Country.mmdb" ]; then
LOG_OUT "Geoip Database Download Success, Check Updated..."
cmp -s /tmp/Country.mmdb "$geoip_path"
if [ "$?" -ne 0 ]; then
@@ -55,6 +56,8 @@ if [ "$?" -eq 0 ] && [ -s "/tmp/Country.mmdb" ]; then
else
LOG_OUT "Updated Geoip Database No Change, Do Nothing..."
fi
elif [ "$DOWNLOAD_RESULT" -eq 2 ]; then
LOG_OUT "Updated Geoip Database No Change, Do Nothing..."
else
LOG_OUT "Geoip Database Update Error, Please Try Again Later..."
fi
@@ -34,8 +34,9 @@ if [ -z "$LGBM_CUSTOM_URL" ]; then
else
DOWNLOAD_URL=$LGBM_CUSTOM_URL
fi
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "/tmp/Model.bin"
if [ "$?" -eq 0 ] && [ -s "/tmp/Model.bin" ]; then
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "/tmp/Model.bin" "$lgbm_path"
DOWNLOAD_RESULT=$?
if [ "$DOWNLOAD_RESULT" -eq 0 ] && [ -s "/tmp/Model.bin" ]; then
LOG_OUT "LightGBM Model Download Success, Check Updated..."
cmp -s /tmp/Model.bin "$lgbm_path"
if [ "$?" -ne "0" ]; then
@@ -47,6 +48,8 @@ if [ "$?" -eq 0 ] && [ -s "/tmp/Model.bin" ]; then
else
LOG_OUT "Updated LightGBM Model No Change, Do Nothing..."
fi
elif [ "$DOWNLOAD_RESULT" -eq 2 ]; then
LOG_OUT "Updated LightGBM Model No Change, Do Nothing..."
else
LOG_OUT "LightGBM Model Update Error, Please Try Again Later..."
fi
@@ -1,161 +0,0 @@
#!/bin/bash
. /usr/share/openclash/openclash_ps.sh
. /lib/functions.sh
. /usr/share/openclash/ruby.sh
. /usr/share/openclash/log.sh
. /usr/share/openclash/openclash_curl.sh
. /usr/share/openclash/uci.sh
set_lock() {
exec 877>"/tmp/lock/openclash_rule.lock" 2>/dev/null
flock -x 877 2>/dev/null
}
del_lock() {
flock -u 877 2>/dev/null
rm -rf "/tmp/lock/openclash_rule.lock" 2>/dev/null
}
set_lock
inc_job_counter
yml_other_rules_dl()
{
local section="$1"
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
LOG_OUT "Warrning: Multiple Other-Rules-Configurations Enabled, Ignore..."
return
fi
config_get "rule_name" "$section" "rule_name" ""
LOG_OUT "Start Downloading Third Party Rules in Use..."
if [ "$rule_name" = "lhie1" ]; then
if [ "$github_address_mod" != "0" ]; then
if [ "$github_address_mod" == "https://cdn.jsdelivr.net/" ] || [ "$github_address_mod" == "https://fastly.jsdelivr.net/" ] || [ "$github_address_mod" == "https://testingcf.jsdelivr.net/" ]; then
DOWNLOAD_URL="${github_address_mod}gh/dler-io/Rules@master/Clash/Rule.yaml"
else
DOWNLOAD_URL="${github_address_mod}https://raw.githubusercontent.com/dler-io/Rules/master/Clash/Rule.yaml"
fi
else
DOWNLOAD_URL="https://raw.githubusercontent.com/dler-io/Rules/master/Clash/Rule.yaml"
fi
fi
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "/tmp/rules.yaml"
if [ "$?" -eq 0 ] && [ -s "/tmp/rules.yaml" ]; then
LOG_OUT "Download Successful, Start Preprocessing Rule File..."
sed -i '1i rules:' /tmp/rules.yaml
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
begin
YAML.load_file('/tmp/rules.yaml');
rescue Exception => e
YAML.LOG('Error: Unable To Parse Updated Rules File,【${rule_name}:' + e.message + '】');
system 'rm -rf /tmp/rules.yaml 2>/dev/null';
end
" 2>/dev/null >> $LOG_FILE
if [ $? -ne 0 ]; then
LOG_OUT "Error: Ruby Works Abnormally, Please Check The Ruby Library Depends!"
rm -rf /tmp/rules.yaml >/dev/null 2>&1
SLOG_CLEAN
del_lock
exit 0
elif [ ! -f "/tmp/rules.yaml" ]; then
LOG_OUT "Error:【$rule_name】Rule File Format Validation Failed, Please Try Again Later..."
rm -rf /tmp/rules.yaml >/dev/null 2>&1
SLOG_CLEAN
del_lock
exit 0
elif ! "$(ruby_read "/tmp/rules.yaml" ".key?('rules')")" ; then
LOG_OUT "Error: Updated Others Rules【$rule_name】Has No Rules Field, Update Exit..."
rm -rf /tmp/rules.yaml >/dev/null 2>&1
SLOG_CLEAN
del_lock
exit 0
#校验是否含有新策略组
elif ! "$(ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
Value = YAML.load_file('/usr/share/openclash/res/${rule_name}.yaml');
Value_1 = YAML.load_file('/tmp/rules.yaml');
OLD_GROUP = Value['rules'].collect{|x| x.split(',')[2] or x.split(',')[1]}.map(&:strip).reject{|g| ['DIRECT', 'REJECT', 'REJECT-DROP', 'PASS'].include?(g)}.uniq.sort;
NEW_GROUP = Value_1['rules'].collect{|x| x.split(',')[2] or x.split(',')[1]}.map(&:strip).reject{|g| ['DIRECT', 'REJECT', 'REJECT-DROP', 'PASS'].include?(g)}.uniq.sort;
if OLD_GROUP.eql?(NEW_GROUP) then
puts true
else
puts false
end
")" && [ -f "/usr/share/openclash/res/${rule_name}.yaml" ]; then
LOG_OUT "Error: Updated Others Rules【$rule_name】Has Incompatible Proxy-Group, Update Exit, Please Wait For OpenClash Update To Adapt..."
rm -rf /tmp/rules.yaml >/dev/null 2>&1
SLOG_CLEAN
del_lock
exit 0
fi
#取出规则部分
ruby_read "/tmp/rules.yaml" ".select {|x| 'rule-providers' == x or 'rules' == x }.to_yaml" > "$OTHER_RULE_FILE"
#合并
cat "$OTHER_RULE_FILE" > "/tmp/rules.yaml" 2>/dev/null
rm -rf /tmp/other_rule* 2>/dev/null
LOG_OUT "Check The Downloaded Rule File For Updates..."
cmp -s /usr/share/openclash/res/"$rule_name".yaml /tmp/rules.yaml
if [ "$?" -ne "0" ]; then
LOG_OUT "Detected that The Downloaded Rule File Has Been Updated, Starting To Replace..."
mv /tmp/rules.yaml /usr/share/openclash/res/"$rule_name".yaml >/dev/null 2>&1
LOG_OUT "Other Rules【$rule_name】Update Successful!"
restart=1
else
LOG_OUT "Updated Other Rules【$rule_name】No Change, Do Nothing!"
fi
else
LOG_OUT "Other Rules【$rule_name】Update Error, Please Try Again Later..."
fi
}
LOG_FILE="/tmp/openclash.log"
RUlE_SOURCE=$(uci_get_config "rule_source")
github_address_mod=$(uci_get_config "github_address_mod" || echo 0)
restart=0
if [ "$RUlE_SOURCE" = "0" ]; then
LOG_OUT "Other Rules Not Enable, Update Stop!"
else
OTHER_RULE_FILE="/tmp/other_rule.yaml"
CONFIG_FILE=$(uci_get_config "config_path")
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
if [ -z "$CONFIG_FILE" ]; then
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
CONFIG_FILE="/etc/openclash/config/config.yaml"
CONFIG_NAME="config.yaml"
fi
config_load "openclash"
config_foreach yml_other_rules_dl "other_rules" "$CONFIG_NAME"
if [ -z "$rule_name" ]; then
LOG_OUT "Get Other Rules Settings Faild, Update Stop!"
fi
fi
rm -rf /tmp/rules.yaml >/dev/null 2>&1
SLOG_CLEAN
dec_job_counter_and_restart "$restart"
del_lock
@@ -27,13 +27,13 @@ local self_status = SYS.exec(string.format('ps -w |grep -v grep |grep -c "opencl
local select_logic = FS.uci_get_config("config", "stream_auto_select_logic") or "urltest"
if not type then
print(os.date("%Y-%m-%d %H:%M:%S").." ".."Error: Streaming Unlock Has No Parameter of Type, Exiting...")
print(os.date("%Y-%m-%d %H:%M:%S").." [Error] Streaming Unlock Has No Parameter of Type, Exiting...")
os.exit(0)
elseif router_self_proxy == 0 then
print(os.date("%Y-%m-%d %H:%M:%S").." ".."Error: Streaming Unlock Could not Work Because of Router-Self Proxy Disabled, Exiting...")
print(os.date("%Y-%m-%d %H:%M:%S").." [Error] Streaming Unlock Could not Work Because of Router-Self Proxy Disabled, Exiting...")
os.exit(0)
elseif tonumber(self_status) > 1 then
print(os.date("%Y-%m-%d %H:%M:%S").." ".."Error: Multiple Scripts Running, Exiting...")
print(os.date("%Y-%m-%d %H:%M:%S").." [Error] Multiple Scripts Running, Exiting...")
os.exit(0)
end
@@ -148,9 +148,9 @@ function unlock_auto_select()
--test now proxy
region = proxy_unlock_test()
if table_include(groups, now_name) then
now = os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..group_show.."】"
now = os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..group_show.."】"
else
now = os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..group_show.." ➟ "..now_name.."】"
now = os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..group_show.." ➟ "..now_name.."】"
end
if status ~= 2 and status ~= 4 then
region = proxy_unlock_test()
@@ -244,7 +244,7 @@ function unlock_auto_select()
end
end
if #(value.all) == 0 then
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..no_nodes_filter)
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..no_nodes_filter)
break
end
--loop proxy test
@@ -274,16 +274,16 @@ function unlock_auto_select()
end
end
if #(proxies) == 0 then
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..group_show.."】"..no_nodes_filter)
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..group_show.."】"..no_nodes_filter)
break
end
for p = 1, #(proxies) do
proxy = proxies[p]
if table_include(groups, proxy) then
group_now = get_group_now(info, proxy)
now = os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..group_show.." ➟ "..group_now.."】"
now = os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..group_show.." ➟ "..group_now.."】"
else
now = os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..group_show.." ➟ "..proxy.."】"
now = os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..group_show.." ➟ "..proxy.."】"
end
--skip tested proxy
while true do
@@ -303,7 +303,7 @@ function unlock_auto_select()
table.insert(full_support_list, {value.all[i], group_name, proxy, region})
if not all_test then
print(now..full_support.."【"..region.."】")
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..select_success.."【"..proxy.."】"..area_i18.."【"..region.."】")
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..select_success.."【"..proxy.."】"..area_i18.."【"..region.."】")
else
print(now..full_support.."【"..region.."】")
end
@@ -312,7 +312,7 @@ function unlock_auto_select()
table.insert(full_support_list, {value.all[i], group_name, proxy})
if not all_test then
print(now..full_support_no_area)
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..select_success.."【"..proxy.."】")
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..select_success.."【"..proxy.."】")
else
print(now..full_support_no_area)
end
@@ -372,16 +372,16 @@ function unlock_auto_select()
end
region = proxy_unlock_test()
if table_include(groups, now_name) then
now = os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..group_show.."】"
now = os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..group_show.."】"
else
now = os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..group_show.." ➟ "..now_name.."】"
now = os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..group_show.." ➟ "..now_name.."】"
end
if status == 2 then
if region ~= "" then
table.insert(full_support_list, {value.all[i], group_name, value.all[i], region})
if not all_test then
print(now..full_support.."【"..region.."】")
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..select_success.."【"..get_group_now(info, now_name).."】"..area_i18.."【"..region.."】")
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..select_success.."【"..get_group_now(info, now_name).."】"..area_i18.."【"..region.."】")
else
print(now..full_support.."【"..region.."】")
end
@@ -390,7 +390,7 @@ function unlock_auto_select()
table.insert(full_support_list, {value.all[i], group_name, value.all[i]})
if not all_test then
print(now..full_support_no_area)
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..select_success.."【"..get_group_now(info, now_name).."】")
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..select_success.."【"..get_group_now(info, now_name).."】")
else
print(now..full_support_no_area)
end
@@ -469,24 +469,24 @@ function unlock_auto_select()
group_now = group_now .. area_i18 .. "【"..v[4].."】"
end
if #full_support_list > 0 then
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..select_all_full_support..group_now)
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..select_all_full_support..group_now)
elseif #no_old_region_unlock > 0 then
if not all_test then
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..select_success_no_old_region..group_now)
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..select_success_no_old_region..group_now)
else
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..select_all_no_old_region..group_now)
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..select_all_no_old_region..group_now)
end
elseif #other_region_unlock > 0 then
if not all_test then
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..select_faild_other_region..group_now)
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..select_faild_other_region..group_now)
else
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..select_all_other_region..group_now)
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..select_all_other_region..group_now)
end
else
if not all_test then
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..select_faild..group_now)
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..select_faild..group_now)
else
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..select_all_faild..group_now)
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..select_all_faild..group_now)
end
end
close_connections()
@@ -499,7 +499,7 @@ function unlock_auto_select()
else
group_now = value.name.." ➟ "..proxy_default
end
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..select_faild.."【"..group_now.."】")
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..select_faild.."【"..group_now.."】")
end
end
elseif #nodes_filter(get_group_now(info, value.name), info) ~= 0 then
@@ -509,12 +509,12 @@ function unlock_auto_select()
if not all_test then
print(now..full_support.."【"..region.."】")
end
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..select_success.."【"..get_group_now(info, value.name).."】"..area_i18.."【"..region.."】")
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..select_success.."【"..get_group_now(info, value.name).."】"..area_i18.."【"..region.."】")
else
if not all_test then
print(now..full_support_no_area)
end
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..value.name.."】"..select_success.."【"..get_group_now(info, value.name).."】")
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..value.name.."】"..select_success.."【"..get_group_now(info, value.name).."】")
end
if not all_test then
break
@@ -548,7 +548,7 @@ function unlock_auto_select()
if status == 2 and not all_test then break end
end
if not group_match and not auto_get_group then
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." "..gorup_i18.."【"..key_group.."】"..no_group_find)
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." "..gorup_i18.."【"..key_group.."】"..no_group_find)
end
--write cache
FS.writefile(unlock_cache_file, JSON.stringify(unlock_cache_info))
@@ -705,7 +705,7 @@ function table_sort_by_cache(t)
end
end
if #tab > 0 then
print(os.date("%Y-%m-%d %H:%M:%S").." "..type.." Group:".."【"..group_match_name.."】".."Cached Compliant Nodes Number:".."【"..#(tab).."】"..", Cached Non-compliant Nodes Number:".."【"..#(tab_b).."】"..", Prioritize Testing With Cached Compliant Nodes...")
print(os.date("%Y-%m-%d %H:%M:%S").." [Info] "..type.." Group:".."【"..group_match_name.."】".."Cached Compliant Nodes Number:".."【"..#(tab).."】"..", Cached Non-compliant Nodes Number:".."【"..#(tab_b).."】"..", Prioritize Testing With Cached Compliant Nodes...")
end
for k,v in pairs(tab_b) do table.insert(tab, v) end
return tab
@@ -1582,7 +1582,7 @@ function network_test()
return
end
end
print(os.date("%Y-%m-%d %H:%M:%S").." Error: Network Anomaly, Suspend Unlock Detection...")
print(os.date("%Y-%m-%d %H:%M:%S").." [Error] Network Anomaly, Suspend Unlock Detection...")
end
network_test()
@@ -19,15 +19,15 @@ inc_job_counter
restart=0
if [ -n "$1" ] && [ "$1" != "one_key_update" ]; then
[ ! -f "/tmp/openclash_last_version" ] && /usr/share/openclash/openclash_version.sh "$1" 2>/dev/null
/usr/share/openclash/openclash_version.sh "$1" 2>/dev/null
elif [ -n "$2" ]; then
[ ! -f "/tmp/openclash_last_version" ] && /usr/share/openclash/openclash_version.sh "$2" 2>/dev/null
/usr/share/openclash/openclash_version.sh "$2" 2>/dev/null
else
[ ! -f "/tmp/openclash_last_version" ] && /usr/share/openclash/openclash_version.sh 2>/dev/null
/usr/share/openclash/openclash_version.sh 2>/dev/null
fi
if [ ! -f "/tmp/openclash_last_version" ]; then
LOG_OUT "Error: Failed to get version information, please try again later..."
LOG_ERROR "Failed to get version information, please try again later..."
SLOG_CLEAN
dec_job_counter_and_restart "$restart"
del_lock
@@ -66,7 +66,7 @@ github_address_mod=$(uci_get_config "github_address_mod" || echo 0)
#一键更新
if [ "$1" = "one_key_update" ]; then
if [ "$github_address_mod" = "0" ] && [ -z "$2" ]; then
LOG_OUT "Tip: If the download fails, try setting the CDN in Overwrite Settings - General Settings - Github Address Modify Options"
LOG_TIP "If the download fails, try setting the CDN in Overwrite Settings - General Settings - Github Address Modify Options"
fi
if [ -n "$2" ]; then
/usr/share/openclash/openclash_core.sh "Meta" "$1" "$2" >/dev/null 2>&1 &
@@ -79,12 +79,12 @@ if [ "$1" = "one_key_update" ]; then
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"
LOG_TIP "If the download fails, try setting the CDN in Overwrite Settings - General Settings - Github Address Modify Options"
fi
fi
if [ -n "$OP_CV" ] && [ -n "$OP_LV" ] && version_compare "$OP_CV" "$OP_LV" && [ -f "$LAST_OPVER" ]; then
LOG_OUT "Tip: Start downloading【OpenClash - v$LAST_VER】..."
LOG_TIP "Start downloading【OpenClash - v$LAST_VER】..."
if [ "$github_address_mod" != "0" ]; then
if [ "$github_address_mod" == "https://cdn.jsdelivr.net/" ] || [ "$github_address_mod" == "https://fastly.jsdelivr.net/" ] || [ "$github_address_mod" == "https://testingcf.jsdelivr.net/" ]; then
if [ -x "/bin/opkg" ]; then
@@ -120,16 +120,16 @@ if [ -n "$OP_CV" ] && [ -n "$OP_LV" ] && version_compare "$OP_CV" "$OP_LV" && [
retry_count=$((retry_count + 1))
if [ "$pkg_update_success" = "false" ]; then
download_result=0
DOWNLOAD_RESULT=0
else
rm -rf "$DOWNLOAD_PATH" >/dev/null 2>&1
LOG_OUT "Tip:【$retry_count/$max_retries】【OpenClash - v$LAST_VER】Downloading..."
SHOW_DOWNLOAD_PROGRESS=1 DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "$DOWNLOAD_PATH"
download_result=$?
LOG_TIP "【$retry_count/$max_retries】【OpenClash - v$LAST_VER】Downloading..."
SHOW_DOWNLOAD_PROGRESS=1 DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "$DOWNLOAD_PATH" "$DOWNLOAD_PATH"
DOWNLOAD_RESULT=$?
fi
if [ "$download_result" -eq 0 ]; then
LOG_OUT "Tip:【$retry_count/$max_retries】【OpenClash - v$LAST_VER】Download successful, start pre update test..."
if [ "$DOWNLOAD_RESULT" -ne 1 ]; then
LOG_TIP "【$retry_count/$max_retries】【OpenClash - v$LAST_VER】Download successful, start pre update test..."
pre_test_success=false
pkg_update_success=true
@@ -162,18 +162,18 @@ if [ -n "$OP_CV" ] && [ -n "$OP_LV" ] && version_compare "$OP_CV" "$OP_LV" && [
fi
if [ "$pre_test_success" = "true" ]; then
LOG_OUT "Tip:【$retry_count/$max_retries】【OpenClash - v$LAST_VER】Pre update test passed, ready to update and please do not refresh the page and other operations..."
LOG_TIP "【$retry_count/$max_retries】【OpenClash - v$LAST_VER】Pre update test passed, ready to update and please do not refresh the page and other operations..."
break
else
if [ "$retry_count" -lt "$max_retries" ]; then
LOG_OUT "Error:【$retry_count/$max_retries】【OpenClash - v$LAST_VER】Pre update test failed..."
LOG_ERROR "【$retry_count/$max_retries】【OpenClash - v$LAST_VER】Pre update test failed..."
sleep 2
continue
else
if [ -x "/bin/opkg" ]; then
LOG_OUT "Error:【OpenClash - v$LAST_VER】Pre update test failed after 3 attempts, the file is saved in /tmp/openclash.ipk, please try to update manually with【opkg install /tmp/openclash.ipk】"
LOG_ERROR "【OpenClash - v$LAST_VER】Pre update test failed after 3 attempts, the file is saved in /tmp/openclash.ipk, please try to update manually with【opkg install /tmp/openclash.ipk】"
elif [ -x "/usr/bin/apk" ]; then
LOG_OUT "Error:【OpenClash - v$LAST_VER】Pre update test failed after 3 attempts, the file is saved in /tmp/openclash.apk, please try to update manually with【apk add -q --force-overwrite --clean-protected --allow-untrusted /tmp/openclash.apk】"
LOG_ERROR "【OpenClash - v$LAST_VER】Pre update test failed after 3 attempts, the file is saved in /tmp/openclash.apk, please try to update manually with【apk add -q --force-overwrite --clean-protected --allow-untrusted /tmp/openclash.apk】"
fi
SLOG_CLEAN
@@ -184,11 +184,11 @@ if [ -n "$OP_CV" ] && [ -n "$OP_LV" ] && version_compare "$OP_CV" "$OP_LV" && [
fi
else
if [ "$retry_count" -lt "$max_retries" ]; then
LOG_OUT "Error:【$retry_count/$max_retries】【OpenClash - v$LAST_VER】Download failed..."
LOG_ERROR "【$retry_count/$max_retries】【OpenClash - v$LAST_VER】Download failed..."
sleep 2
continue
else
LOG_OUT "Error:【OpenClash - v$LAST_VER】Download Failed after 3 attempts, please check the network or try again later!"
LOG_ERROR "【OpenClash - v$LAST_VER】Download Failed after 3 attempts, please check the network or try again later!"
rm -rf /tmp/openclash.ipk >/dev/null 2>&1
rm -rf /tmp/openclash.apk >/dev/null 2>&1
SLOG_CLEAN
@@ -224,12 +224,20 @@ fi
trap 'del_update_lock; exit' INT TERM EXIT
LOG_OUT()
LOG_ERROR()
{
if [ -n "${1}" ]; then
echo -e "${1}" > $START_LOG
echo -e "${LOGTIME} ${1}" >> $LOG_FILE
fi
if [ -n "${1}" ]; then
echo -e "${1}" > $START_LOG
echo -e "${LOGTIME} [error] ${1}" >> $LOG_FILE
fi
}
LOG_TIP()
{
if [ -n "${1}" ]; then
echo -e "${1}" > $START_LOG
echo -e "${LOGTIME} [tip] ${1}" >> $LOG_FILE
fi
}
SLOG_CLEAN()
@@ -297,16 +305,13 @@ install_missing_packages() {
fi
}
uci -q set openclash.config.enable=0
uci -q commit openclash
install_retry_count=0
max_install_retries=3
install_success=false
while [ $install_retry_count -lt $max_install_retries ]; do
install_retry_count=$((install_retry_count + 1))
LOG_OUT "Tip:【$install_retry_count/$max_install_retries】Installing the new version, please do not refresh the page or do other operations..."
LOG_TIP "【$install_retry_count/$max_install_retries】Installing the new version, please do not refresh the page or do other operations..."
packages_to_check="luci-compat kmod-inet-diag kmod-nft-tproxy kmod-ipt-nat iptables-mod-tproxy iptables-mod-extra ipset"
installed_before=""
@@ -333,7 +338,7 @@ while [ $install_retry_count -lt $max_install_retries ]; do
install_missing_packages "$installed_before"
break
else
LOG_OUT "Error:【$install_retry_count/$max_install_retries】Installation failed..."
LOG_ERROR "【$install_retry_count/$max_install_retries】Installation failed..."
if [ $install_retry_count -lt $max_install_retries ]; then
sleep 3
fi
@@ -346,15 +351,11 @@ if [ "$install_success" = true ]; then
elif [ -x "/usr/bin/apk" ]; then
rm -rf /tmp/openclash.apk >/dev/null 2>&1
fi
LOG_OUT "Tip: OpenClash update successful, about to restart!"
uci -q set openclash.config.enable=1
uci -q commit openclash
/etc/init.d/openclash restart 2>/dev/null
else
if [ -x "/bin/opkg" ]; then
LOG_OUT "Error: OpenClash update failed after 3 attempts, the file is saved in /tmp/openclash.ipk, please try to update manually with【opkg install /tmp/openclash.ipk】"
LOG_ERROR "OpenClash update failed after 3 attempts, the file is saved in /tmp/openclash.ipk, please try to update manually with【opkg install /tmp/openclash.ipk】"
elif [ -x "/usr/bin/apk" ]; then
LOG_OUT "Error: OpenClash update failed after 3 attempts, the file is saved in /tmp/openclash.apk, please try to update manually with【apk add -q --force-overwrite --clean-protected --allow-untrusted /tmp/openclash.apk】"
LOG_ERROR "OpenClash update failed after 3 attempts, the file is saved in /tmp/openclash.apk, please try to update manually with【apk add -q --force-overwrite --clean-protected --allow-untrusted /tmp/openclash.apk】"
fi
SLOG_CLEAN
fi
@@ -364,7 +365,7 @@ EOF
chmod 4755 /tmp/openclash_update.sh
if [ ! -f "/tmp/openclash_update.sh" ] || [ ! -s "/tmp/openclash_update.sh" ] || [ ! -x "/tmp/openclash_update.sh" ]; then
LOG_OUT "Error: Failed to create update script!"
LOG_ERROR "Failed to create update script!"
rm -rf /tmp/openclash_update.sh
del_lock
exit 1
@@ -376,7 +377,7 @@ EOF
while [ $retry_count -lt $max_retries ]; do
retry_count=$((retry_count + 1))
LOG_OUT "Tip:【$retry_count/$max_retries】Attempting to start update service..."
LOG_TIP "【$retry_count/$max_retries】Attempting to start update service..."
ubus call service add '{"name":"openclash_update","instances":{"update":{"command":["/tmp/openclash_update.sh"],"stdout":true,"stderr":true,"env":{"LAST_VER":"'"$LAST_VER"'"}}}}' >/dev/null 2>&1
@@ -387,22 +388,22 @@ EOF
break
else
if [ $retry_count -lt $max_retries ]; then
LOG_OUT "Error:【$retry_count/$max_retries】Service start failed, retrying in 2 seconds..."
LOG_ERROR "【$retry_count/$max_retries】Service start failed, retrying in 2 seconds..."
sleep 2
fi
fi
done
if [ "$service_started" = false ]; then
LOG_OUT "Error: Failed to start update service after 3 attempts, please check and try again later..."
LOG_ERROR "Failed to start update service after 3 attempts, please check and try again later..."
fi
(sleep 15; rm -f /tmp/openclash_update.sh) &
else
if [ ! -f "$LAST_OPVER" ] || [ -z "$OP_CV" ] || [ -z "$OP_LV" ]; then
LOG_OUT "Error: Failed to get version information, please try again later..."
LOG_ERROR "Failed to get version information, please try again later..."
else
LOG_OUT "Tip: OpenClash has not been updated, stop continuing!"
LOG_TIP "OpenClash has not been updated, stop continuing!"
fi
SLOG_CLEAN
dec_job_counter_and_restart "$restart"
@@ -32,8 +32,6 @@ version_compare() {
return 1
}
TIME=$(date "+%Y-%m-%d-%H")
CHTIME=$(date "+%Y-%m-%d-%H" -r "/tmp/openclash_last_version" 2>/dev/null)
DOWNLOAD_FILE="/tmp/openclash_last_version"
RELEASE_BRANCH=$(uci_get_config "release_branch" || echo "master")
if [ -x "/bin/opkg" ]; then
@@ -47,24 +45,23 @@ if [ -n "$1" ]; then
github_address_mod="$1"
fi
if [ "$TIME" != "$CHTIME" ]; then
if [ "$github_address_mod" != "0" ]; then
if [ "$github_address_mod" == "https://cdn.jsdelivr.net/" ] || [ "$github_address_mod" == "https://fastly.jsdelivr.net/" ] || [ "$github_address_mod" == "https://testingcf.jsdelivr.net/" ]; then
DOWNLOAD_URL="${github_address_mod}gh/vernesong/OpenClash@package/${RELEASE_BRANCH}/version"
else
DOWNLOAD_URL="${github_address_mod}https://raw.githubusercontent.com/vernesong/OpenClash/package/${RELEASE_BRANCH}/version"
fi
if [ "$github_address_mod" != "0" ]; then
if [ "$github_address_mod" == "https://cdn.jsdelivr.net/" ] || [ "$github_address_mod" == "https://fastly.jsdelivr.net/" ] || [ "$github_address_mod" == "https://testingcf.jsdelivr.net/" ]; then
DOWNLOAD_URL="${github_address_mod}gh/vernesong/OpenClash@package/${RELEASE_BRANCH}/version"
else
DOWNLOAD_URL="https://raw.githubusercontent.com/vernesong/OpenClash/package/${RELEASE_BRANCH}/version"
DOWNLOAD_URL="${github_address_mod}https://raw.githubusercontent.com/vernesong/OpenClash/package/${RELEASE_BRANCH}/version"
fi
else
DOWNLOAD_URL="https://raw.githubusercontent.com/vernesong/OpenClash/package/${RELEASE_BRANCH}/version"
fi
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "$DOWNLOAD_FILE"
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "$DOWNLOAD_FILE" "$DOWNLOAD_FILE"
if [ "$?" -eq 0 ]; then
OP_LV=$(sed -n 1p $DOWNLOAD_FILE 2>/dev/null |awk -F 'v' '{print $2}' |awk -F '.' '{print $2$3}' 2>/dev/null)
if [ -n "$OP_CV" ] && [ -n "$OP_LV" ] && version_compare "$OP_CV" "$OP_LV" && [ -f "$DOWNLOAD_FILE" ]; then
sed -i '/^https:/,$d' $DOWNLOAD_FILE
fi
if [ "$?" -eq 0 ]; then
OP_LV=$(sed -n 1p $DOWNLOAD_FILE 2>/dev/null |awk -F 'v' '{print $2}' |awk -F '.' '{print $2$3}' 2>/dev/null)
if [ -n "$OP_CV" ] && [ -n "$OP_LV" ] && version_compare "$OP_CV" "$OP_LV" && [ -f "$DOWNLOAD_FILE" ]; then
sed -i '/^https:/,$d' $DOWNLOAD_FILE
fi
fi
del_lock
@@ -30,7 +30,7 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
begin
Value = YAML.load_file('$CONFIG_FILE');
rescue Exception => e
YAML.LOG('Error: Load File Failed,【' + e.message + '】');
YAML.LOG_ERROR('Load File Failed,【' + e.message + '】');
exit;
end;
@@ -69,7 +69,7 @@ begin
sub_servers = IO.popen(syscall).read.split(/\n+/)
servers_to_process.concat(sub_servers) if sub_servers
rescue Exception => e
YAML.LOG('Warning: Failed to parse subscription file with Lua helper ' + path + ': ' + e.message)
YAML.LOG_WARN('Failed to parse subscription file with Lua helper ' + path + ': ' + e.message)
end
end
end
@@ -149,7 +149,7 @@ begin
system(set_commands.join('; ')) if not set_commands.empty?
end
rescue Exception => e
YAML.LOG('Error: Set Proxies Address Skip Failed,【' + e.message + '】');
YAML.LOG_ERROR('Set Proxies Address Skip Failed,【' + e.message + '】');
end" 2>/dev/null >> $LOG_FILE
}
@@ -193,10 +193,10 @@ fi
LOGSIZE=`ls -l /tmp/openclash.log |awk '{print int($5/1024)}'`
if [ "$LOGSIZE" -gt "$log_size" ]; then
: > /tmp/openclash.log
LOG_OUT "Watchdog: Log Size Limit, Clean Up All Log Records..."
LOG_WATCHDOG "Log Size Limit, Clean Up All Log Records..."
fi
## 转发顺序
## 防火墙检查
if [ "$FIREWALL_RELOAD" -le "$MAX_FIREWALL_RELOAD" ]; then
if [ -z "$FW4" ]; then
nat_last_line=$(iptables -t nat -nL PREROUTING --line-number 2>/dev/null | awk 'END {print $1}')
@@ -211,7 +211,13 @@ fi
fi
if ([ "$nat_last_line" != "$nat_op_line" ] && [ -n "$nat_op_line" ]) || ([ "$man_last_line" != "$man_op_line" ] && [ -n "$man_op_line" ]); then
LOG_OUT "Watchdog: Setting Firewall For Rules Order..."
## 转发顺序检查
LOG_WATCHDOG "Setting Firewall For Rules Order..."
/etc/init.d/openclash reload "firewall"
let FIREWALL_RELOAD++
elif [ -n "$(ip tuntap list |grep utun)" ] && [ -z "$(ip route list table 354)" ]; then
## 路由表检查
LOG_WATCHDOG "Setting Firewall For IP Rules Table Recreate..."
/etc/init.d/openclash reload "firewall"
let FIREWALL_RELOAD++
else
@@ -339,7 +345,7 @@ fi
## DNS转发劫持
if [ "$enable_redirect_dns" = "1" ]; then
if [ -z "$(uci -q get dhcp.@dnsmasq[0].server |grep "$dns_port")" ] || [ ! -z "$(uci -q get dhcp.@dnsmasq[0].server |awk -F ' ' '{print $2}')" ]; then
LOG_OUT "Watchdog: Force Reset DNS Hijack..."
LOG_WATCHDOG "Force Reset DNS Hijack..."
uci -q del dhcp.@dnsmasq[-1].server
uci -q add_list dhcp.@dnsmasq[0].server=127.0.0.1#"$dns_port"
uci -q delete dhcp.@dnsmasq[0].resolvfile
@@ -361,67 +367,64 @@ fi
CFG_UPDATE_INT=$(expr "$CFG_UPDATE_INT" + 1)
fi
##Dler Cloud Checkin
/usr/share/openclash/openclash_dler_checkin.lua >/dev/null 2>&1
##STREAMING_UNLOCK_CHECK
if [ "$stream_auto_select" -eq 1 ] && [ "$router_self_proxy" -eq 1 ]; then
[ "$stream_auto_select_interval" -ne "$stream_auto_select_interval_now" ] && STREAM_AUTO_SELECT=1 && stream_auto_select_interval="$stream_auto_select_interval_now"
if [ "$STREAM_AUTO_SELECT" -ne 0 ]; then
if [ "$(expr "$STREAM_AUTO_SELECT" % "$stream_auto_select_interval_now")" -eq 0 ] || [ "$STREAM_AUTO_SELECT" -eq 1 ]; then
if [ "$stream_auto_select_netflix" -eq 1 ]; then
LOG_OUT "Tip: Start Auto Select Proxy For Netflix Unlock..."
LOG_TIP "Start Auto Select Proxy For Netflix Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "Netflix" >> $LOG_FILE
fi
if [ "$stream_auto_select_disney" -eq 1 ]; then
LOG_OUT "Tip: Start Auto Select Proxy For Disney Plus Unlock..."
LOG_TIP "Start Auto Select Proxy For Disney Plus Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "Disney Plus" >> $LOG_FILE
fi
if [ "$stream_auto_select_google_not_cn" -eq 1 ]; then
LOG_OUT "Tip: Start Auto Select Proxy For Google Not CN Unlock..."
LOG_TIP "Start Auto Select Proxy For Google Not CN Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "Google" >> $LOG_FILE
fi
if [ "$stream_auto_select_ytb" -eq 1 ]; then
LOG_OUT "Tip: Start Auto Select Proxy For YouTube Premium Unlock..."
LOG_TIP "Start Auto Select Proxy For YouTube Premium Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "YouTube Premium" >> $LOG_FILE
fi
if [ "$stream_auto_select_prime_video" -eq 1 ]; then
LOG_OUT "Tip: Start Auto Select Proxy For Amazon Prime Video Unlock..."
LOG_TIP "Start Auto Select Proxy For Amazon Prime Video Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "Amazon Prime Video" >> $LOG_FILE
fi
if [ "$stream_auto_select_hbo_max" -eq 1 ]; then
LOG_OUT "Tip: Start Auto Select Proxy For HBO Max Unlock..."
LOG_TIP "Start Auto Select Proxy For HBO Max Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "HBO Max" >> $LOG_FILE
fi
if [ "$stream_auto_select_tvb_anywhere" -eq 1 ]; then
LOG_OUT "Tip: Start Auto Select Proxy For TVB Anywhere+ Unlock..."
LOG_TIP "Start Auto Select Proxy For TVB Anywhere+ Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "TVB Anywhere+" >> $LOG_FILE
fi
if [ "$stream_auto_select_dazn" -eq 1 ]; then
LOG_OUT "Tip: Start Auto Select Proxy For DAZN Unlock..."
LOG_TIP "Start Auto Select Proxy For DAZN Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "DAZN" >> $LOG_FILE
fi
if [ "$stream_auto_select_paramount_plus" -eq 1 ]; then
LOG_OUT "Tip: Start Auto Select Proxy For Paramount Plus Unlock..."
LOG_TIP "Start Auto Select Proxy For Paramount Plus Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "Paramount Plus" >> $LOG_FILE
fi
if [ "$stream_auto_select_discovery_plus" -eq 1 ]; then
LOG_OUT "Tip: Start Auto Select Proxy For Discovery Plus Unlock..."
LOG_TIP "Start Auto Select Proxy For Discovery Plus Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "Discovery Plus" >> $LOG_FILE
fi
if [ "$stream_auto_select_bilibili" -eq 1 ]; then
LOG_OUT "Tip: Start Auto Select Proxy For Bilibili Unlock..."
LOG_TIP "Start Auto Select Proxy For Bilibili Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "Bilibili" >> $LOG_FILE
fi
if [ "$stream_auto_select_openai" -eq 1 ]; then
LOG_OUT "Tip: Start Auto Select Proxy For OpenAI Unlock..."
LOG_TIP "Start Auto Select Proxy For OpenAI Unlock..."
/usr/share/openclash/openclash_streaming_unlock.lua "OpenAI" >> $LOG_FILE
fi
fi
fi
STREAM_AUTO_SELECT=$(expr "$STREAM_AUTO_SELECT" + 1)
elif [ "$router_self_proxy" != "1" ] && [ "$stream_auto_select" -eq 1 ]; then
LOG_OUT "Error: Streaming Unlock Could not Work Because of Router-Self Proxy Disabled, Exiting..."
LOG_ERROR "Streaming Unlock Could not Work Because of Router-Self Proxy Disabled, Exiting..."
fi
SLOG_CLEAN
File diff suppressed because it is too large. Load diff
@@ -1,188 +0,0 @@
300英雄,300hero-cn.rules
永恒之塔-台服,Aion-TW.rules
美国卡车模拟国际服,American-Truck-Simulator.rules
太空狼人杀,Among Us.rules
圣歌,Anthem.rules
Apex-uu,Apex-uu.rules
Apex英雄,Apex.rules
方舟:生存进化,ARK--Survival-Evolved.rules
武装突袭3,Arma3.rules
刺客信条:奥德赛,Assassin's-Creed-Odyssey.rules,Assassins-Creed-Odyssey.rules
刺客信条:起源,Assassin's-Creed-Origins.rules,Assassins-Creed-Origins.rules
Atlas-全区,Atlas.rules
战网,Battle-net-tw.rules
战地1,Battlefield-1.rules
战地4,BattleField-4.rules
戰地5,Battlefield-Ⅴ.rules,Battlefield-5.rules
黑色沙漠,Black-Desert.rules
黑色幸存者,BlackSurvivor.rules
灵剑台服,Blade&Soul TW.rules
剑灵-日服,Blade-&-Soul-jp.rules
剑灵-国服-南天国(测试版),Blood-&-Soul-CN-TestServer-NantianGuo-Alpha.rules
剑灵-国服全部区服(UU规则),Blood-&-Soul-CN.rules
无主之地3,Borderlands3-asia.rules
泡泡战士-跑跑卡丁车-韩服,BubbleFighter-KartRider-KR.rules
绕过大陆和局域网,BypassCNandLan.rules
绕过大陆和局域网someip,BypassCNandLan_someip.rules
使命召唤4:现代战争重置版,Call-Of-Duty-4-Modern-Warfare.rules
使命召唤16&19:现代战争I&II,Call-Of-Duty-Modern-Warfare.rules
使命召唤15亚服,Call-Of-Duty15-Asia.rules
使命召唤17:冷战,Call-Of-Duty17-ColdWar.rules
仅代理中国IP,China-IP-only.rules
英雄连2,Company-Of-Heroes-2.rules
反恐精英:全球攻势,CS-GO.rules
反恐精英:全球攻势-港服(tx),CSGO-HKtx.rules
反恐精英:全球攻势-港服(uu),CSGO-HKuu.rules
反恐精英:全球攻势-日服(tx),CSGO-JPtx.rules
反恐精英:全球攻势-美服(tx),CSGO-UStx.rules
黑暗之魂3,Dark-Souls-3.rules
不屈不挠,Dauntless.rules
DayZ steam,DayZ.rules
黎明杀机,Dead-by-Daylight.rules
命运2-全服(tx),Destiny2-Alltx.rules
命运2-全服(uu),Destiny2-Alluu.rules
天命2-亚服/命运2-亚服,Destiny2-Asia.rules
天命2-欧服/命运2-欧服,Destiny2-EU.rules
命运2-steam,Destiny2-steam.rules
天命2-美服/命运2-美服,Destiny2-US.rules
暗黑破坏神2:重制版,Diablo-2-Resurrected.rules
暗黑破坏神3-亚服,Diablo3-Asia.rules
暗黑破坏神3-美服,Diablo3-US.rules
暗黑破坏神4-港服,DiabloIV-HK.rules
脏弹-Steam,Dirty-Bomb.rules
Discord语音,Discord-All.rules
饥荒-steam,Don't-Starve-steam.rules,Dont-Starve-steam.rules
刀塔霸业,Dota-Underlords.rules
DOTA2-日服,Dota2-jp.rules
精英-危险,Elite-Dangerous.rules
逃离塔科夫,Escape-from-Tarkov.rules
欧卡2所有分区-UU,Euro-Truck-Simulator-2.rules
Eve-online欧服,Eve-online.rules
糖豆人,Fall-Guys.rules
FIFA19,FiFa19-INT.rules
FIFA20,FIFA20.rules
最终幻想14国服,FINAL-FANTASY-XIV-cn.rules
最终幻想14,Final-Fantasy-XIV.rules
荣耀战魂,For-Honour.rules
堡垒之夜亚服,Fortnite-AS.rules
堡垒之夜-国服,Fortnite-cn.rules
极限竞速地平线4,Forza-Horizon-4.rules
极限竞速地平线5,Forza-Horizon-5.rules
极限竞速7,Forza-Motorsport-7.rules
侠盗猎车手5,GTA-V.rules
基佬大乱斗Gang Beasts,Gang-Beasts.rules
原神-港澳台服,GenshinImpact.exe_SSTAP.rules
鹅鸭杀,Goose-Goose-Duck-HK.rules
Grand Theft Auto V,Grand Theft Auto V.rules
激战2,Guild-Wars-2.rules
巫师昆特牌国际服,Gwent_The-Witcher-Card-game.rules
光环:士官长合集,Halo-The-Master-Chief-Collection.rules
风暴英雄,heros of the storm-kr.rules
杀手2外服,HITMAN2.rules
荒野行动PC版-国服,HuangYeXingDong-cn.rules
猎杀对决,Hunt-Showdown-Asia.rules
叛乱:沙漠风暴,Insurgency-Sandstorm.rules
Jump大乱斗,Jump-Force.rules
跑跑卡丁车(韩服),KartRider.rules
酷狗回国,KuGou-cn.rules
Kurtzpel,Kurtzpel.rules
求生之路2-Test,L4D2-Test.rules
英雄联盟-日服,League-of-Legends-jp.rules
英雄联盟-韩服,League-of-Legends-kr.rules
英雄联盟PBE,League-of-Legends-PBE.rules
英雄联盟-台服+Garena平台(2018-12-19更新),League-of-Legends-tw+Garena(2018-12-19).rules
英雄联盟-台服,League-of-Legends-tw.rules
英雄联盟-美服,League-of-Legends-us.rules
致命公司,Lethal Company.rules
失落的方舟韩服,Lost-Ark.rules
失落的方舟俄服,Lostark-RU.rules
冒险岛,Maplestory-us.rules
心灵终结,MentalOmega.rules
微软模拟飞行年度版,Microsoft-Flight-Simulator-Game-Of-The-Year-Edition.rules
微软模拟飞行,Microsoft-Flight-Simulator.rules
巨硬商店,Microsoft-Srote.rules
我的世界-地下城,Minecraft-Dungeons.rules
传奇4-亚服,MIR4-asia.rules
误造,Miscreated.rules
怪兽世界猎人steam版,Monster-Hunter-World.rules
万智牌:竞技场-国际服,MTG-Arena.rules
奇迹传奇MU2,MU2.rules
NBA-2K19,NBA-2K19.rules
NBA2K20,NBA2K20.rules
仁王,NIOH.rules
橘子客户端-UU,Origin.rules
Osu!,Osu!.rules
守望先锋2,Overwatch-2-Asia-Singapore.rules
守望先锋-亚服,Overwatch-Asia.rules
守望先锋-美服,Overwatch-US.rules
流亡黯道-国际服,Path Of Exile.rules
流放之路,PathOfexile.rules
梦幻之星2-日服(tx),PHANTASY STAR ONLINE2-JPtx.rules
行星边际2,PlanetSide-2.rules
绝地求生大逃杀,PlayerUnknown's-Battlegrounds-update.rules,PlayerUnknowns-Battlegrounds-update.rules
实况足球-2018,Pro-Evolution-Soccer-2018.rules
实况足球-2019,Pro-Evolution-Soccer-2019.rules
绝地求生亚服&东南亚服,PUBG-Asia&-Southeast-Asia.rules
绝地求生亚服,PUBG-Asis.rules
绝地求生国际服,PUBG-INT.rules
绝地求生韩服,PUBG-kakao.rules
绝地求生低配版-Garena,PUBGLite-Garena.rules
绝地求生轻量版-WEB客户端,PUBGLITE-WEB.rules
R2竞技场服,R2Arena.rules
R2俄服官服,R2RU.rules
R2美服,R2US.rules
仙境传说2-us,Ragnarok-Online-2-us.rules
仙境传说OL台湾,Ragnarok-Online-tw.rules
荒野大镖客2,Red-dead-redemption2.rules
无限法则,Ring-of-Elysium-asia.rules
Roblox,Roblox.rules
Scum人渣-全球服,Scum.rules
影之诗,Shadowverse.rules
不代理中国IP且绕过局域网(精简版CNIP表),Skip-all-China-IP-mini-and-LAN.rules
灵魂行者-台服,Soul-Worker.rules
星际公民,Star-Citizen.rules
星球大战2前线,Star-Wars-BattlefrontII.rules
StarCraft 2 亚服,StarCraft-2-asia.rules
星际争霸2国服,StarCraftⅡ-cn.rules
星露谷物语,Stardew Valley.rules
Steam-社区(Beta),Steam.rules
极限巅峰,Steep.rules
街头霸王5,Street-Fighter-V.rules
仅代理Telegram,Telegram.rules
神谕之战,TERA.rules
飙酷车神,The-Crew.rules
飙酷车神2,The-Crew2.rules
上古卷轴OL,The-Elder-Scrolls-Online.rules
天涯明月刀-台服,TianYaMingYueDao-tw.rules
泰坦陨落2,TiTanFall2.rules
新枫之谷,TMS.rules
幽灵行动:荒野,Tom-Clancy's-Ghost-Recon-Wildlands.rules,Tom-Clancys-Ghost-Recon-Wildlands.rules
彩虹六号-异种-全部,Tom-Clancy's-Rainbow-Six-Extraction-all.rules,Tom-Clancys-Rainbow-Six-Extraction-all.rules
彩虹六号-围攻-全部,Tom-Clancy's-Rainbow-Six-Siege-all.rules,Tom-Clancys-Rainbow-Six-Siege-all.rules
彩虹六号-围攻-EAS,Tom-Clancy's-Rainbow-Six-Siege-EAS.rules,Tom-Clancys-Rainbow-Six-Siege-EAS.rules
全境封锁2,Tom-clancy's-The-Division-2.rules,Tom-clancys-The-Division-2.rules
全境封锁,Tom-clancy's-The-Division.rules,Tom-clancys-The-Division.rules
Twitch直播,Twitch.rules
未转变者Unturned,Unturned.rules
无畏契约,Valorant.rules
VRchat,VRchat.rules
战争雷霆-steam,War-thunder-steam.rules
战争前线,Warface.rules
星际战甲,Warframe.rules
看门狗,Watch-Dogs.rules
看门狗2,Watch-Dogs2.rules
求生意志OL,Will-To-Live-Online.rules
坦克世界-亚服,World-of-Tanks-Asia.rules
坦克世界闪电战,World-of-Tanks-Blitz.rules
坦克世界-国服,World-of-Tanks-cn.rules
魔兽世界台服,World-of-warcraft-tw.rules
战舰世界国服UU,World-of-Warships-CN.rules
战舰世界欧服,World-of-warships-EU.rules
战舰世界-美服,World-of-Warships-US.rules
战舰世界-亚服,World-of-Warships.rules
World War 3,World-War-3.rules
僵尸世界大战,Worldwar-Z.rules
魔兽世界-欧服,WoW-EU.rules
游戏王决斗链接,YO-GI-HO delulinks.rules
游侠对战平台,YouXiaDuiZhanPingTai.rules
YY语音,YY-cn.rules
@@ -1,438 +0,0 @@
rules:
- RULE-SET,AdBlock,AdBlock
- RULE-SET,HTTPDNS,HTTPDNS
- RULE-SET,Special,DIRECT
- RULE-SET,Netflix,Netflix
- RULE-SET,Disney Plus,Disney Plus
- RULE-SET,YouTube,YouTube
- RULE-SET,Max,Max
- RULE-SET,Spotify,Spotify
- RULE-SET,Abema TV,Asian TV
- RULE-SET,Bahamut,Asian TV
- RULE-SET,DMM,Asian TV
- RULE-SET,Fox+,Asian TV
- RULE-SET,Hulu Japan,Asian TV
- RULE-SET,IQ,Asian TV
- RULE-SET,Japonx,Asian TV
- RULE-SET,JOOX,Asian TV
- RULE-SET,KKBOX,Asian TV
- RULE-SET,KKTV,Asian TV
- RULE-SET,Line TV,Asian TV
- RULE-SET,myTV SUPER,Asian TV
- RULE-SET,Niconico,Asian TV
- RULE-SET,ViuTV,Asian TV
- RULE-SET,ABC,Global TV
- RULE-SET,Amazon,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,Hulu,Global TV
- RULE-SET,Pandora,Global TV
- RULE-SET,PBS,Global TV
- RULE-SET,Pornhub,Global TV
- RULE-SET,Soundcloud,Global TV
- RULE-SET,Bilibili,CN Mainland TV
- RULE-SET,IQIYI,CN Mainland TV
- RULE-SET,Letv,CN Mainland TV
- RULE-SET,Netease Music,CN Mainland TV
- RULE-SET,Tencent Video,CN Mainland TV
- RULE-SET,WeTV,CN Mainland TV
- RULE-SET,Youku,CN Mainland TV
- RULE-SET,Telegram,Telegram
- RULE-SET,Crypto,Crypto
- RULE-SET,Discord,Discord
- RULE-SET,Google FCM,Google FCM
- RULE-SET,Microsoft,Microsoft
- RULE-SET,AI Suite,AI Suite
- RULE-SET,PayPal,PayPal
- RULE-SET,Scholar,Scholar
- RULE-SET,Speedtest,Speedtest
- RULE-SET,Steam,Steam
- RULE-SET,TikTok,TikTok
- RULE-SET,Apple Music,Apple TV
- RULE-SET,Apple News,Apple TV
- RULE-SET,Apple TV,Apple TV
- RULE-SET,Apple,Apple
- 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-providers:
AdBlock:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/AdBlock.yaml
path: "./Rules/AdBlock"
interval: 86400
HTTPDNS:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/HTTPDNS.yaml
path: "./Rules/HTTPDNS"
interval: 86400
Special:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Special.yaml
path: "./Rules/Special"
interval: 86400
PROXY:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Proxy.yaml
path: "./Rules/Proxy"
interval: 86400
Domestic:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Domestic.yaml
path: "./Rules/Domestic"
interval: 86400
Domestic IPs:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Domestic%20IPs.yaml
path: "./Rules/Domestic_IPs"
interval: 86400
LAN:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/LAN.yaml
path: "./Rules/LAN"
interval: 86400
Netflix:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Netflix.yaml
path: "./Rules/Media/Netflix"
interval: 86400
Spotify:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Spotify.yaml
path: "./Rules/Media/Spotify"
interval: 86400
YouTube:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/YouTube.yaml
path: "./Rules/Media/YouTube"
interval: 86400
Max:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Max.yaml
path: "./Rules/Media/Max"
interval: 86400
Bilibili:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Bilibili.yaml
path: "./Rules/Media/Bilibili"
interval: 86400
IQ:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/IQ.yaml
path: "./Rules/Media/IQI"
interval: 86400
IQIYI:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/IQIYI.yaml
path: "./Rules/Media/IQYI"
interval: 86400
Letv:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Letv.yaml
path: "./Rules/Media/Letv"
interval: 86400
Netease Music:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/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://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Tencent%20Video.yaml
path: "./Rules/Media/Tencent_Video"
interval: 86400
Youku:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Youku.yaml
path: "./Rules/Media/Youku"
interval: 86400
WeTV:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/WeTV.yaml
path: "./Rules/Media/WeTV"
interval: 86400
ABC:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/ABC.yaml
path: "./Rules/Media/ABC"
interval: 86400
Abema TV:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Abema%20TV.yaml
path: "./Rules/Media/Abema_TV"
interval: 86400
Amazon:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Amazon.yaml
path: "./Rules/Media/Amazon"
interval: 86400
Apple Music:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/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://testingcf.jsdelivr.net/gh/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://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Apple%20TV.yaml
path: "./Rules/Media/Apple_TV"
interval: 86400
Bahamut:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Bahamut.yaml
path: "./Rules/Media/Bahamut"
interval: 86400
BBC iPlayer:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/BBC%20iPlayer.yaml
path: "./Rules/Media/BBC_iPlayer"
interval: 86400
DAZN:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/DAZN.yaml
path: "./Rules/Media/DAZN"
interval: 86400
Discovery Plus:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/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://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Disney%20Plus.yaml
path: "./Rules/Media/Disney_Plus"
interval: 86400
DMM:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/DMM.yaml
path: "./Rules/Media/DMM"
interval: 86400
encoreTVB:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/encoreTVB.yaml
path: "./Rules/Media/encoreTVB"
interval: 86400
F1 TV:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/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://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Fox%20Now.yaml
path: "./Rules/Media/Fox_Now"
interval: 86400
Fox+:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Fox%2B.yaml
path: "./Rules/Media/Fox+"
interval: 86400
Hulu Japan:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Hulu%20Japan.yaml
path: "./Rules/Media/Hulu_Japan"
interval: 86400
Hulu:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Hulu.yaml
path: "./Rules/Media/Hulu"
interval: 86400
Japonx:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Japonx.yaml
path: "./Rules/Media/Japonx"
interval: 86400
JOOX:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/JOOX.yaml
path: "./Rules/Media/JOOX"
interval: 86400
KKBOX:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/KKBOX.yaml
path: "./Rules/Media/KKBOX"
interval: 86400
KKTV:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/KKTV.yaml
path: "./Rules/Media/KKTV"
interval: 86400
Line TV:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/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://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/myTV%20SUPER.yaml
path: "./Rules/Media/myTV_SUPER"
interval: 86400
Niconico:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Niconico.yaml
path: "./Rules/Media/Niconico"
interval: 86400
Pandora:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Pandora.yaml
path: "./Rules/Media/Pandora"
interval: 86400
PBS:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/PBS.yaml
path: "./Rules/Media/PBS"
interval: 86400
Pornhub:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Pornhub.yaml
path: "./Rules/Media/Pornhub"
interval: 86400
Soundcloud:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/Soundcloud.yaml
path: "./Rules/Media/Soundcloud"
interval: 86400
ViuTV:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Media/ViuTV.yaml
path: "./Rules/Media/ViuTV"
interval: 86400
Telegram:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Telegram.yaml
path: "./Rules/Telegram"
interval: 86400
Crypto:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Crypto.yaml
path: "./Rules/Crypto"
interval: 86400
Discord:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Discord.yaml
path: "./Rules/Discord"
interval: 86400
Steam:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Steam.yaml
path: "./Rules/Steam"
interval: 86400
TikTok:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/TikTok.yaml
path: "./Rules/TikTok"
interval: 86400
Speedtest:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Speedtest.yaml
path: "./Rules/Speedtest"
interval: 86400
PayPal:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/PayPal.yaml
path: "./Rules/PayPal"
interval: 86400
Microsoft:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Microsoft.yaml
path: "./Rules/Microsoft"
interval: 86400
AI Suite:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/AI%20Suite.yaml
path: "./Rules/AI Suite"
interval: 86400
Apple:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Apple.yaml
path: "./Rules/Apple"
interval: 86400
Google FCM:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Google%20FCM.yaml
path: "./Rules/Google FCM"
interval: 86400
Scholar:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/Scholar.yaml
path: "./Rules/Scholar"
interval: 86400
miHoYo:
type: http
behavior: classical
url: https://testingcf.jsdelivr.net/gh/dler-io/Rules@main/Clash/Provider/miHoYo.yaml
path: "./Rules/miHoYo"
interval: 86400
@@ -1,96 +0,0 @@
放行规则-lhie1(建议置顶并直连),lhie1,classical,dler-io/Rules/master/Clash/Provider/,Special.yaml
放行规则-ACL4SSR(建议置顶并直连),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/,UnBan.yaml
国内IP白名单(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/,Domestic IPs.yaml
国内域名白名单(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/,Domestic.yaml
国外常用网站合集(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/,Proxy.yaml
广告规则(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/,AdBlock.yaml
微软服务,lhie1,classical,dler-io/Rules/master/Clash/Provider/,Microsoft.yaml
HTTPDNS(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/,HTTPDNS.yaml
ABC,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,ABC.yaml
Abema TV,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Abema TV.yaml
AbemaTV(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,AbemaTV.yaml,AbemaTV-ACL4SSR.yaml
Adobe,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Adobe.yaml
AI Suite,lhie1,classical,dler-io/Rules/master/Clash/Provider/,AI Suite.yaml
Amazon(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Amazon.yaml,Amazon-ACL4SSR.yaml
Amazon,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Amazon.yaml
AmazonIp,ACL4SSR,ipcidr,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,AmazonIp.yaml
Apple News(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Apple News.yaml
Apple TV(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Apple TV.yaml
Apple(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Apple.yaml,Apple-ACL4SSR.yaml
Apple(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/,Apple.yaml,Apple-lhie1.yaml
BBC iPlayer,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,BBC iPlayer.yaml
Bahamut(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Bahamut.yaml,Bahamut-ACL4SSR.yaml
Bahamut(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Bahamut.yaml,Bahamut-lhie1.yaml
BanAD,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/,BanAD.yaml
BanEasyList,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/,BanEasyList.yaml
BanEasyListChina,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/,BanEasyListChina.yaml
BanEasyPrivacy,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/,BanEasyPrivacy.yaml
BanProgramAD,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/,BanProgramAD.yaml
Bilibili(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Bilibili.yaml,Bilibili-ACL4SSR.yaml
Bilibili,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Bilibili.yaml
BilibiliHMT,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,BilibiliHMT.yaml
Blizzard,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Blizzard.yaml
ChinaCompanyIp,ACL4SSR,ipcidr,ACL4SSR/ACL4SSR/master/Clash/Providers/,ChinaCompanyIp.yaml
ChinaDomain,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/,ChinaDomain.yaml
ChinaIp(By ACL4SSR),ACL4SSR,ipcidr,ACL4SSR/ACL4SSR/master/Clash/Providers/,ChinaIp.yaml,ChinaIp-ACL4SSR.yaml
ChinaMedia,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/,ChinaMedia.yaml
DAZN(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,DAZN.yaml,DAZN-lhie1.yaml
Developer,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Developer.yaml
Disney Plus,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Disney Plus.yaml
DisneyPlus(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,DisneyPlus.yaml,DisneyPlus-ACL4SSR.yaml
Download,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/,Download.yaml
EHGallery,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,EHGallery.yaml
Epic,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Epic.yaml
Fox Now,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Fox Now.yaml
Fox+,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Fox+.yaml
Google,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Google.yaml
GoogleCN,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,GoogleCN.yaml
GoogleFCM,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,GoogleFCM.yaml
HBO(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,HBO.yaml,HBO-ACL4SSR.yaml
HBO MAX(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Max.yaml,MAX-lhie1.yaml
Hulu Japan,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Hulu Japan.yaml
Hulu(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Hulu.yaml,Hulu-lhie1.yaml
JOOX(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,JOOX.yaml,JOOX-lhie1.yaml
Japonx,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Japonx.yaml
KKBOX(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,KKBOX.yaml,KKBOX-lhie1.yaml
KKTV(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,KKTV.yaml,KKTV-lhie1.yaml
Letv,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Letv.yaml
Line TV,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Line TV.yaml
LocalAreaNetwork,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/,LocalAreaNetwork.yaml
MOO,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,MOO.yaml
Microsoft(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Microsoft.yaml,Microsoft-ACL4SSR.yaml
NetEaseMusic,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,NetEaseMusic.yaml
Netease Music,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Netease Music.yaml
Netflix(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Netflix.yaml,Netflix-ACL4SSR.yaml
Netflix(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Netflix.yaml,Netflix-lhie1.yaml
OneDrive(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,OneDrive.yaml,OneDrive-ACL4SSR.yaml
PBS(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,PBS.yaml,PBS-lhie1.yaml
Pandora(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Pandora.yaml,Pandora-lhie1.yaml
PayPal(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/,PayPal.yaml,PayPal-lhie1.yaml
Porn,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Porn.yaml
Pornhub(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Pornhub.yaml,Pornhub-lhie1.yaml
ProxyGFWlist,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/,ProxyGFWlist.yaml
ProxyLite,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/,ProxyLite.yaml
ProxyMedia,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/,ProxyMedia.yaml
Scholar(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Scholar.yaml,Scholar-ACL4SSR.yaml
Sony,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Sony.yaml
Soundcloud(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Soundcloud.yaml,Soundcloud-lhie1.yaml
Speedtest,lhie1,classical,dler-io/Rules/master/Clash/Provider/,Speedtest.yaml
Spotify(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Spotify.yaml,Spotify-ACL4SSR.yaml
Spotify(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Spotify.yaml,Spotify-lhie1.yaml
Steam(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Steam.yaml,Steam-ACL4SSR.yaml
Steam,lhie1,classical,dler-io/Rules/master/Clash/Provider/,Steam.yaml
SteamCN,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,SteamCN.yaml
Telegram(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Telegram.yaml,Telegram-ACL4SSR.yaml
Telegram(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/,Telegram.yaml,Telegram-lhie1.yaml
Tencent Video,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Tencent Video.yaml
ViuTV(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,ViuTV.yaml,ViuTV-lhie1.yaml
Xbox,ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,Xbox.yaml
YouTube Music,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,YouTube Music.yaml
YouTube(By ACL4SSR),ACL4SSR,classical,ACL4SSR/ACL4SSR/master/Clash/Providers/Ruleset/,YouTube.yaml,YouTube-ACL4SSR.yaml
YouTube(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,YouTube.yaml,YouTube-lhie1.yaml
Youku,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,Youku.yaml
encoreTVB(By lhie1),lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,encoreTVB.yaml,encoreTVB-lhie1.yaml
IQIYI,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,IQIYI.yaml
IQ,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,IQ.yaml
myTV SUPER,lhie1,classical,dler-io/Rules/master/Clash/Provider/Media/,myTV SUPER.yaml
@@ -1,9 +1,6 @@
默认(附带用于Clash的AdGuard DNS),default_with_clash_adg.yml,https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/default_with_clash_adg.yml
无Urltest,no_urltest.ini,https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/no_urltest.ini
带Urltest,urltest.ini,https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/urltest.ini
ConnersHua 神机规则 Pro,connershua_pro.ini,https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/connershua_new.ini
lhie1 洞主规则(使用 Clash 分组规则),lhie1_clash.ini,https://gist.githubusercontent.com/vernesong/4c27ed54ab2a5fedd9c4011389ac11ed/raw/lhie1_clash.ini
lhie1 洞主规则完整版,lhie1_dler.ini,https://gist.githubusercontent.com/vernesong/4c27ed54ab2a5fedd9c4011389ac11ed/raw/lhie1_dler.ini
ACL4SSR 规则标准版,ACL4SSR.ini,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR.ini
ACL4SSR 规则 AdblockPlus,ACL4SSR_AdblockPlus.ini,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_AdblockPlus.ini
ACL4SSR 规则 BackCN,ACL4SSR_BackCN.ini,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_BackCN.ini
@@ -8,9 +8,23 @@ write_ruby_part()
fi
if [ "$OVERWRITE_PARENT" = "yaml_overwrite" ]; then
mkdir -p /tmp/yaml_openclash_ruby_parts 2>/dev/null
echo "$part" >> "/tmp/yaml_openclash_ruby_parts/$sid"
echo "threads << Thread.new do begin $part; rescue Exception => e; YAML.LOG_ERROR('Set Custom Overwrite Script Failed,【%s】' % [e.message]); end; end" >> "/tmp/yaml_openclash_ruby_parts/$sid"
else
echo "$part" >> /tmp/yaml_openclash_ruby_parse
echo "threads << Thread.new do begin $part; rescue Exception => e; YAML.LOG_ERROR('Set Custom Overwrite Script Failed,【%s】' % [e.message]); end; end" >> /tmp/yaml_openclash_ruby_parse
fi
}
run_ruby_part()
{
local part="$1" show_error="${2:-true}"
if [ -z "$part" ]; then
return
fi
if [ "$show_error" = "false" ] || [ "$show_error" = "0" ]; then
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "begin $part; end" 2>/dev/null
else
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "begin $part; rescue Exception => e; YAML.LOG_ERROR('Set Custom Overwrite Script Failed,【%s】' % [e.message]); end" 2>/dev/null
fi
}
@@ -37,13 +51,13 @@ ruby_read()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); puts Value$2"
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if Value$2 then puts Value$2 end"
if [ -n "$(echo "$2" |grep '.to_yaml' 2>/dev/null)" ]; then
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null |sed '1d' 2>/dev/null
run_ruby_part "$RUBY_YAML_PARSE" "false" |sed '1d' 2>/dev/null
else
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
run_ruby_part "$RUBY_YAML_PARSE" "false"
fi
}
@@ -51,213 +65,234 @@ ruby_read_hash()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
return
fi
RUBY_YAML_PARSE="Value = $1; puts Value$2"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
RUBY_YAML_PARSE="Value = $1; if Value$2 then puts Value$2 end"
run_ruby_part "$RUBY_YAML_PARSE" "false"
}
ruby_read_hash_arr()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); Value$2.each do |i| puts i$3 end"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if Value$2 then Value$2.each do |i| if i$3 then puts i$3 end; end; end"
run_ruby_part "$RUBY_YAML_PARSE" "false"
}
ruby_edit()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
return
fi
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; Value$2=$3"
write_ruby_part "threads << Thread.new do $RUBY_YAML_PARSE end"
write_ruby_part "$RUBY_YAML_PARSE"
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); Value$2=$3; File.open('$1','w') {|f| YAML.dump(Value, f)}"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
run_ruby_part "$RUBY_YAML_PARSE"
}
ruby_cover()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
return
fi
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; if File::exist?('$3') then Value_1 = YAML.load_file('$3'); if not '$4'.empty? then Value$2=Value_1['$4']; else Value$2=Value_1 end else if not '$4'.empty? then Value.delete('$4'); end; end"
write_ruby_part "threads << Thread.new do $RUBY_YAML_PARSE end"
write_ruby_part "$RUBY_YAML_PARSE"
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if File::exist?('$3') then Value_1 = YAML.load_file('$3'); if not '$4'.empty? then Value$2=Value_1['$4']; else Value$2=Value_1 end else if not '$4'.empty? then Value.delete('$4'); end; end; File.open('$1','w') {|f| YAML.dump(Value, f)}"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
run_ruby_part "$RUBY_YAML_PARSE"
}
ruby_merge()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; Value_1 = YAML.load_file('$3'); Value$2.merge!(Value_1$4)"
write_ruby_part "threads << Thread.new do $RUBY_YAML_PARSE end"
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); Value_1 = YAML.load_file('$3'); Value$2.merge!(Value_1$4); File.open('$1','w') {|f| YAML.dump(Value, f)}"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; Value_1 = YAML.load_file('$3'); if not Value$2 then Value$2 = {}; end; if Value_1$4 && Value_1$4.is_a?(Hash) then Value$2.merge!(Value_1$4) end"
write_ruby_part "$RUBY_YAML_PARSE"
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if File::exist?('$3') then Value_1 = YAML.load_file('$3'); if not Value$2 then Value$2 = {}; end; if Value_1$4 && Value_1$4.is_a?(Hash) then Value$2.merge!(Value_1$4) end end; File.open('$1','w') {|f| YAML.dump(Value, f)}"
run_ruby_part "$RUBY_YAML_PARSE"
}
ruby_uniq()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; Value$2=Value$2.uniq"
write_ruby_part "threads << Thread.new do $RUBY_YAML_PARSE end"
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); Value$2=Value$2.uniq; File.open('$1','w') {|f| YAML.dump(Value, f)}"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; if Value$2 then Value$2=Value$2.uniq; end"
write_ruby_part "$RUBY_YAML_PARSE"
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if Value$2 then Value$2=Value$2.uniq; end; File.open('$1','w') {|f| YAML.dump(Value, f)}"
run_ruby_part "$RUBY_YAML_PARSE"
}
ruby_merge_hash()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; Value$2.merge!($3)"
write_ruby_part "threads << Thread.new do $RUBY_YAML_PARSE end"
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); Value$2.merge!($3); File.open('$1','w') {|f| YAML.dump(Value, f)}"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; if not Value$2 then Value$2 = {}; end; Value$2.merge!({$3})"
write_ruby_part "$RUBY_YAML_PARSE"
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if not Value$2 then Value$2 = {}; end; Value$2.merge!({$3}); File.open('$1','w') {|f| YAML.dump(Value, f)}"
run_ruby_part "$RUBY_YAML_PARSE"
}
ruby_arr_add_file()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; Value_1 = YAML.load_file('$4'); Value_1$5.reverse.each{|x| Value$2.insert($3,x)}; Value$2=Value$2.uniq"
write_ruby_part "threads << Thread.new do $RUBY_YAML_PARSE end"
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ] || [ -z "$5" ]; then
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); Value_1 = YAML.load_file('$4'); Value_1$5.reverse.each{|x| Value$2.insert($3,x)}; Value$2=Value$2.uniq; File.open('$1','w') {|f| YAML.dump(Value, f)}"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; if File::exist?('$4') then Value_1 = YAML.load_file('$4'); if not Value$2 or Value$2.nil? then Value$2 = []; end; if Value_1$5 && Value_1$5.is_a?(Array) then idx = [$3.to_i, 0].max; idx = [idx, Value$2.length].min; Value_1$5.reverse.each{|x| Value$2.insert(idx,x); idx += 1}; Value$2=Value$2.uniq end end"
write_ruby_part "$RUBY_YAML_PARSE"
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if File::exist?('$4') then Value_1 = YAML.load_file('$4'); if not Value$2 or Value$2.nil? then Value$2 = []; end; if Value_1$5 && Value_1$5.is_a?(Array) then idx = [$3.to_i, 0].max; idx = [idx, Value$2.length].min; Value_1$5.reverse.each{|x| Value$2.insert(idx,x); idx += 1}; Value$2=Value$2.uniq end end; File.open('$1','w') {|f| YAML.dump(Value, f)}"
run_ruby_part "$RUBY_YAML_PARSE"
}
ruby_arr_head_add_file()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; Value_1 = YAML.load_file('$3'); Value$2=(Value_1$4+Value$2).uniq"
write_ruby_part "threads << Thread.new do $RUBY_YAML_PARSE end"
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ]; then
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); Value_1 = YAML.load_file('$3'); Value$2=(Value_1$4+Value$2).uniq; File.open('$1','w') {|f| YAML.dump(Value, f)}"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; if File::exist?('$3') then Value_1 = YAML.load_file('$3'); if not Value$2 or Value$2.nil? then Value$2 = []; end; if Value_1$4 && Value_1$4.is_a?(Array) then Value$2=(Value_1$4+Value$2).uniq else Value$2=Value$2.uniq end end"
write_ruby_part "$RUBY_YAML_PARSE"
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if File::exist?('$3') then Value_1 = YAML.load_file('$3'); if not Value$2 or Value$2.nil? then Value$2 = []; end; if Value_1$4 && Value_1$4.is_a?(Array) then Value$2=(Value_1$4+Value$2).uniq else Value$2=Value$2.uniq end end; File.open('$1','w') {|f| YAML.dump(Value, f)}"
run_ruby_part "$RUBY_YAML_PARSE"
}
ruby_arr_insert()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; if not Value$2 or Value$2.nil? then Value$2 = []; end; Value$2=Value$2.insert($3,'$4').uniq"
write_ruby_part "threads << Thread.new do $RUBY_YAML_PARSE end"
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ]; then
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if not Value$2 or Value$2.nil? then Value$2 = []; end; Value$2=Value$2.insert($3,'$4').uniq; File.open('$1','w') {|f| YAML.dump(Value, f)}"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; if not Value$2 or Value$2.nil? then Value$2 = []; end; idx = [$3.to_i, 0].max; idx = [idx, Value$2.length].min; Value$2=Value$2.insert(idx,'$4').uniq"
write_ruby_part "$RUBY_YAML_PARSE"
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if not Value$2 or Value$2.nil? then Value$2 = []; end; idx = [$3.to_i, 0].max; idx = [idx, Value$2.length].min; Value$2=Value$2.insert(idx,'$4').uniq; File.open('$1','w') {|f| YAML.dump(Value, f)}"
run_ruby_part "$RUBY_YAML_PARSE"
}
ruby_arr_insert_hash()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; if not Value$2 or Value$2.nil? then Value$2 = []; end; Value$2=Value$2.insert($3,$4).uniq"
write_ruby_part "threads << Thread.new do $RUBY_YAML_PARSE end"
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ]; then
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if not Value$2 or Value$2.nil? then Value$2 = []; end; Value$2=Value$2.insert($3,$4).uniq; File.open('$1','w') {|f| YAML.dump(Value, f)}"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; if not Value$2 or Value$2.nil? then Value$2 = []; end; idx = [$3.to_i, 0].max; idx = [idx, Value$2.length].min; Value$2=Value$2.insert(idx,$4).uniq"
write_ruby_part "$RUBY_YAML_PARSE"
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if not Value$2 or Value$2.nil? then Value$2 = []; end; idx = [$3.to_i, 0].max; idx = [idx, Value$2.length].min; Value$2=Value$2.insert(idx,$4).uniq; File.open('$1','w') {|f| YAML.dump(Value, f)}"
run_ruby_part "$RUBY_YAML_PARSE"
}
ruby_arr_insert_arr()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; if not Value$2 or Value$2.nil? then Value$2 = []; end; ${4}.reverse.each{|x| Value$2=Value$2.insert($3,x).uniq}"
write_ruby_part "threads << Thread.new do $RUBY_YAML_PARSE end"
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ]; then
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if not Value$2 or Value$2.nil? then Value$2 = []; end; ${4}.reverse.each{|x| Value$2=Value$2.insert($3,x).uniq}; File.open('$1','w') {|f| YAML.dump(Value, f)}"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; if not Value$2 or Value$2.nil? then Value$2 = []; end; if $4.is_a?(Array) then idx = [$3.to_i, 0].max; idx = [idx, Value$2.length].min; $4.reverse.each{|x| Value$2=Value$2.insert(idx,x); idx += 1}; Value$2=Value$2.uniq end"
write_ruby_part "$RUBY_YAML_PARSE"
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if not Value$2 or Value$2.nil? then Value$2 = []; end; if $4.is_a?(Array) then idx = [$3.to_i, 0].max; idx = [idx, Value$2.length].min; $4.reverse.each{|x| Value$2=Value$2.insert(idx,x); idx += 1}; Value$2=Value$2.uniq end; File.open('$1','w') {|f| YAML.dump(Value, f)}"
run_ruby_part "$RUBY_YAML_PARSE"
}
ruby_delete()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$3" ]; then
return
fi
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; Value$2.delete('$3')"
write_ruby_part "threads << Thread.new do $RUBY_YAML_PARSE end"
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); Value$2.delete('$3'); File.open('$1','w') {|f| YAML.dump(Value, f)}"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
if openclash_custom_overwrite; then
if [ -z "$2" ]; then
RUBY_YAML_PARSE="yaml_file_path='$1'; Value.delete('$3')"
else
RUBY_YAML_PARSE="yaml_file_path='$1'; if Value$2 then if Value$2.is_a?(Hash) then Value$2.delete('$3') elsif Value$2.is_a?(Array) then Value$2.delete('$3') end end"
fi
write_ruby_part "$RUBY_YAML_PARSE"
return
fi
if [ -z "$2" ]; then
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); Value.delete('$3'); File.open('$1','w') {|f| YAML.dump(Value, f)}"
else
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if Value$2 then if Value$2.is_a?(Hash) then Value$2.delete('$3') elsif Value$2.is_a?(Array) then Value$2.delete('$3') end end; File.open('$1','w') {|f| YAML.dump(Value, f)}"
fi
run_ruby_part "$RUBY_YAML_PARSE"
}
ruby_map_edit()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; Value$2.each{|x,y| if x == '$3' then y$4 = '$5' end}"
write_ruby_part "threads << Thread.new do $RUBY_YAML_PARSE end"
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ]; then
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); Value$2.each{|x,y| if x == '$3' then y$4 = '$5' end}; File.open('$1','w') {|f| YAML.dump(Value, f)}"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; if Value$2 && Value$2.is_a?(Hash) then if Value$2['$3'] && Value$2['$3'].is_a?(Hash) then Value$2['$3']$4 = '$5' end end"
write_ruby_part "$RUBY_YAML_PARSE"
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if Value$2 && Value$2.is_a?(Hash) then if Value$2['$3'] && Value$2['$3'].is_a?(Hash) then Value$2['$3']$4 = '$5' end end; File.open('$1','w') {|f| YAML.dump(Value, f)}"
run_ruby_part "$RUBY_YAML_PARSE"
}
ruby_arr_edit()
{
local RUBY_YAML_PARSE
if [ -z "$1" ] || [ -z "$2" ]; then
return
fi
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; Value$2[$3] = '$4'"
write_ruby_part "threads << Thread.new do $RUBY_YAML_PARSE end"
return
fi
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); Value$2.map!{|x| if x$3 == '$4' then x$5='$6'; x else x end }.uniq!; File.open('$1','w') {|f| YAML.dump(Value, f)}"
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "$RUBY_YAML_PARSE" 2>/dev/null
if openclash_custom_overwrite; then
RUBY_YAML_PARSE="yaml_file_path='$1'; if Value$2 && Value$2.is_a?(Array) then"
if [ -n "$3" ] && [ -n "$4" ] && [ -n "$5" ] && [ -n "$6" ]; then
RUBY_YAML_PARSE="$RUBY_YAML_PARSE Value$2.each{|x| if x.is_a?(Hash) && x$3 == '$4' then x$5='$6' end} end"
elif [ -z "$3" ] && [ -n "$4" ] && [ -z "$5" ] && [ -n "$6" ]; then
RUBY_YAML_PARSE="$RUBY_YAML_PARSE Value$2.map!{|x| if x == '$4' then '$6' else x end}; Value$2.uniq! end"
else
return
fi
write_ruby_part "$RUBY_YAML_PARSE"
return
fi
if [ -n "$3" ] && [ -n "$4" ] && [ -n "$5" ] && [ -n "$6" ]; then
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if Value$2 && Value$2.is_a?(Array) then Value$2.map!{|x| if x.is_a?(Hash) && x$3 == '$4' then x$5='$6' end; x}; Value$2.uniq! end; File.open('$1','w') {|f| YAML.dump(Value, f)}"
elif [ -z "$3" ] && [ -n "$4" ] && [ -z "$5" ] && [ -n "$6" ]; then
RUBY_YAML_PARSE="Value = YAML.load_file('$1'); if Value$2 && Value$2.is_a?(Array) then Value$2.map!{|x| if x == '$4' then '$6' else x end}; Value$2.uniq! end; File.open('$1','w') {|f| YAML.dump(Value, f)}"
else
return
fi
run_ruby_part "$RUBY_YAML_PARSE"
}
@@ -83,7 +83,7 @@ yml_auth_get()
if [ -z "$username" ] || [ -z "$password" ]; then
return
else
LOG_OUT "Tip: You have seted the authentication of SOCKS5/HTTP(S) proxy with【$username:$password】..."
LOG_TIP "You have seted the authentication of SOCKS5/HTTP(S) proxy with【$username:$password】..."
echo " - $username:$password" >>/tmp/yaml_openclash_auth
fi
}
@@ -170,7 +170,7 @@ PROXY_GROUPS=$(ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
Value['proxy-groups'].each { |x| puts x['name'] if x.key?('name') }
end
rescue Exception => e
YAML.LOG('Error: proxy-groups Get Failed,【%s】' % [e.message])
YAML.LOG_ERROR('proxy-groups Get Failed,【%s】' % [e.message])
end
" 2>/dev/null)
@@ -206,6 +206,7 @@ yml_dns_get()
config_get "ecs_subnet" "$section" "ecs_subnet" ""
config_get_bool "disable_ipv4" "$section" "disable_ipv4" "0"
config_get_bool "disable_ipv6" "$section" "disable_ipv6" "0"
config_get_bool "disable_reuse" "$section" "disable_reuse" "0"
config_list_foreach "$section" "disable_qtype" set_disable_qtype
if [[ "$ip" =~ "$regex" ]] || [ -n "$(echo "${ip}" | grep -Eo "${regex}")" ]; then
@@ -245,6 +246,7 @@ yml_dns_get()
[ "$ecs_override" = "1" ] && [ -n "$ecs_subnet_param" ] && ecs_override_param="ecs-override=true" || ecs_override_param=""
[ "$disable_ipv4" = "1" ] && disable_ipv4_param="disable-ipv4=true" || disable_ipv4_param=""
[ "$disable_ipv6" = "1" ] && disable_ipv6_param="disable-ipv6=true" || disable_ipv6_param=""
[ "$disable_reuse" = "1" ] && disable_reuse_param="disable-reuse=true" || disable_reuse_param=""
params=""
append_param() {
@@ -263,6 +265,7 @@ yml_dns_get()
append_param "$disable_ipv4_param"
append_param "$disable_ipv6_param"
append_param "$disable_qtype_param"
append_param "$disable_reuse_param"
full_dns_address="$dns_type$dns_address$params"
@@ -327,474 +330,477 @@ begin
config_file = '$5'
Value = YAML.load_file(config_file)
rescue Exception => e
YAML.LOG('Error: Load File Failed,【%s】' % [e.message])
YAML.LOG_ERROR('Load File Failed,【%s】' % [e.message])
exit
end
fake_ip_mode = '$1'
secret = '$2'
controller_port = '$3'
redir_port = '$4'
enable_ipv6 = '$6' == '1'
http_port = '$7'
socks_port = '$8'
log_level = '$9'
mode = '${10}'
en_mode_tun = '$en_mode_tun'
stack_type = '$stack_type'
dns_listen_port = '${13}'
mixed_port = '${14}'
tproxy_port = '${15}'
dns_ipv6 = '${16}' == '1'
store_fake_ip = '${17}' == '1'
enable_sniffer = '${18}' == '1'
geodata_mode = '${19}' == '1'
geodata_loader = '${20}'
append_sniffer_config = '${21}' == '1'
interface_name = '${22}'
tcp_concurrent = '${23}' == '1'
add_default_from_dns = '${25}' == '1'
sniffer_parse_pure_ip = '${26}' == '1'
find_process_mode = '${27}'
fake_ip_range = '${28}'
ipv6_mode = '${29}'
unified_delay = '${31}' == '1'
respect_rules = '${32}' == '1'
fake_ip_filter_mode = '${33}'
routing_mark_setting = '${34}'
quic_gso = '${35}' == '1'
cors_origin = '${36}'
geo_custom_url = '${37}'
geoip_custom_url = '${38}'
geosite_custom_url = '${39}'
geoasn_custom_url = '${40}'
lgbm_auto_update = '${41}' == '1'
lgbm_custom_url = '${42}'
lgbm_update_interval = '${43}'
smart_collect = '${44}' == '1'
smart_collect_size = '${45}'
fake_ip_range6 = '${46}'
default_dashboard = '$default_dashboard'
yacd_type = '$yacd_type'
dashboard_type = '$dashboard_type'
enable_custom_dns = '$enable_custom_dns' == '1'
append_wan_dns = '$append_wan_dns' == '1'
custom_fakeip_filter = '$custom_fakeip_filter' == '1'
china_ip_route = '$china_ip_route' != '0'
china_ip6_route = '$china_ip6_route' != '0'
custom_name_policy = '$custom_name_policy' == '1'
custom_proxy_server_policy = '$custom_proxy_server_policy' == '1'
custom_host = '$custom_host' == '1'
enable_redirect_dns = '$enable_redirect_dns'
Value['dns'] ||= {}
threads = []
threads << Thread.new do
begin
Value['redir-port'] = redir_port.to_i
Value['tproxy-port'] = tproxy_port.to_i
Value['port'] = http_port.to_i
Value['socks-port'] = socks_port.to_i
Value['mixed-port'] = mixed_port.to_i
Value['mode'] = mode
Value['log-level'] = log_level if log_level != '0'
Value['allow-lan'] = true
Value['external-controller'] = '0.0.0.0:' + controller_port
Value['secret'] = secret
Value['bind-address'] = '*'
Value['external-ui'] = '/usr/share/openclash/ui'
Value['external-ui-name'] = default_dashboard
case default_dashboard
when 'dashboard'
if dashboard_type == 'Official'
Value['external-ui-url'] = 'https://codeload.github.com/ayanamist/clash-dashboard/zip/refs/heads/gh-pages'
else
Value['external-ui-url'] = 'https://codeload.github.com/MetaCubeX/Razord-meta/zip/refs/heads/gh-pages'
end
when 'yacd'
if yacd_type == 'Official'
Value['external-ui-url'] = 'https://codeload.github.com/haishanh/yacd/zip/refs/heads/gh-pages'
else
Value['external-ui-url'] = 'https://codeload.github.com/MetaCubeX/Yacd-meta/zip/refs/heads/gh-pages'
end
when 'metacubexd'
Value['external-ui-url'] = 'https://codeload.github.com/MetaCubeX/metacubexd/zip/refs/heads/gh-pages'
when 'zashboard'
Value['external-ui-url'] = 'https://codeload.github.com/Zephyruso/zashboard/zip/refs/heads/gh-pages-cdn-fonts'
end
if !Value.key?('keep-alive-interval') && !Value.key?('keep-alive-idle')
Value['keep-alive-interval'] = 15
Value['keep-alive-idle'] = 600
end
Value['ipv6'] = enable_ipv6
Value['interface-name'] = interface_name if interface_name != '0'
Value['geodata-mode'] = true if geodata_mode
Value['geodata-loader'] = geodata_loader if geodata_loader != '0'
Value['tcp-concurrent'] = true if tcp_concurrent
Value['unified-delay'] = true if unified_delay
Value['find-process-mode'] = find_process_mode if find_process_mode != '0'
(Value['experimental'] ||= {})['quic-go-disable-gso'] = true if quic_gso
if cors_origin != '0'
(Value['external-controller-cors'] ||= {})['allow-origins'] = [cors_origin]
Value['external-controller-cors']['allow-private-network'] = true
end
Value['lgbm-auto-update'] = true if lgbm_auto_update
if lgbm_auto_update
Value['lgbm-url'] = lgbm_custom_url.strip
Value['lgbm-update-interval'] = lgbm_update_interval.to_i
end
if smart_collect
(Value['profile'] ||= {})['smart-collector-size'] = smart_collect_size.to_f
end
Value['geox-url'] ||= {}
if geo_custom_url != '0'
Value['geox-url']['mmdb'] = geo_custom_url
end
if geoip_custom_url != '0'
Value['geox-url']['geoip'] = geoip_custom_url
end
if geosite_custom_url != '0'
Value['geox-url']['geosite'] = geosite_custom_url
end
if geoasn_custom_url != '0'
Value['geox-url']['asn'] = geoasn_custom_url
end
Value['dns']['enable'] = true
Value['dns']['ipv6'] = dns_ipv6
Value['ipv6'] = true if dns_ipv6
if fake_ip_mode == 'redir-host'
Value['dns']['enhanced-mode'] = 'redir-host'
Value['dns'].delete('fake-ip-range')
else
Value['dns']['enhanced-mode'] = 'fake-ip'
Value['dns']['fake-ip-range'] = fake_ip_range
if Value['dns']['ipv6']
Value['dns']['fake-ip-range6'] = fake_ip_range6
end
end
Value['dns']['listen'] = '0.0.0.0:' + dns_listen_port
Value['dns']['respect-rules'] = respect_rules
if enable_sniffer
sniffer_config = {
'enable' => true, 'override-destination' => true,
'sniff' => {'QUIC' => {'ports' => [443]}, 'TLS' => {'ports' => [443, 8443]}, 'HTTP' => {'ports' => [80, '8080-8880'], 'override-destination' => true}},
'force-domain' => ['+.netflix.com', '+.nflxvideo.net', '+.amazonaws.com', '+.media.dssott.com'],
'skip-domain' => ['Mijia Cloud', 'dlg.io.mi.com', '+.oray.com', '+.sunlogin.net', '+.push.apple.com']
}
sniffer_config['force-dns-mapping'] = true if fake_ip_mode == 'redir-host'
sniffer_config['parse-pure-ip'] = true if sniffer_parse_pure_ip
Value['sniffer'] = sniffer_config
if append_sniffer_config && (custom_sniffer = safe_load_yaml('/etc/openclash/custom/openclash_custom_sniffer.yaml'))
Value['sniffer'].merge!(custom_sniffer['sniffer']) if custom_sniffer && custom_sniffer['sniffer']
end
else
Value['sniffer']['enable'] = false if Value.key?('sniffer')
end
if en_mode_tun != '0' || ['2', '3'].include?(ipv6_mode)
Value['tun'] = {
'enable' => true, 'stack' => stack_type, 'device' => 'utun',
'dns-hijack' => ['127.0.0.1:53'], 'endpoint-independent-nat' => true,
'auto-route' => false, 'auto-detect-interface' => false,
'auto-redirect' => false, 'strict-route' => false, 'disable-icmp-forwarding' => false
}
Value['tun'].delete('iproute2-table-index')
else
Value.delete('tun')
end
Value.delete('iptables')
(Value['profile'] ||= {})['store-selected'] = true
Value['profile']['store-fake-ip'] = true if store_fake_ip
Value.delete('ebpf')
if routing_mark_setting == '0'
Value['routing-mark'] = 6666
else
Value.delete('routing-mark')
end
Value.delete('auto-redir')
(Value['ntp'] ||= {})['enable'] = true
Value['ntp']['server'] = 'time.apple.com' if !Value['ntp'].key?('server')
Value['ntp']['port'] = 123 if !Value['ntp'].key?('port')
Value['ntp']['interval'] = 30 if !Value['ntp'].key?('interval')
Value['ntp']['write-to-system'] = true if !Value['ntp'].key?('write-to-system')
rescue Exception => e
YAML.LOG('Error: Set General Failed,【%s】' % [e.message])
end
end
threads << Thread.new do
begin
if enable_custom_dns || append_wan_dns
if (namedns_config = safe_load_yaml('/tmp/yaml_config.namedns.yaml')) && namedns_config['nameserver']
if enable_custom_dns
Value['dns']['nameserver'] = namedns_config['nameserver'].uniq
elsif append_wan_dns
(Value['dns']['nameserver'] ||= []).concat(namedns_config['nameserver']).uniq!
end
if enable_custom_dns && (falldns_config = safe_load_yaml('/tmp/yaml_config.falldns.yaml')) && falldns_config['fallback']
Value['dns']['fallback'] = falldns_config['fallback'].uniq
end
elsif enable_custom_dns
YAML.LOG('Error: Nameserver Option Must Be Setted, Stop Customing DNS Servers')
end
end
rescue Exception => e
YAML.LOG('Error: Set Custom DNS Failed,【%s】' % [e.message])
end
begin
if enable_custom_dns
if (defaultdns_config = safe_load_yaml('/tmp/yaml_config.defaultdns.yaml')) && defaultdns_config['default-nameserver']
(Value['dns']['default-nameserver'] ||= []).concat(defaultdns_config['default-nameserver']).uniq!
end
end
if add_default_from_dns
reg = /^dhcp:\/\/|^system($|:\/\/)|([0-9a-zA-Z-]{1,}\.)+([a-zA-Z]{2,})/
servers_to_check = Value.dig('dns', 'nameserver').to_a | Value.dig('dns', 'fallback').to_a
non_domain_servers = servers_to_check.reject { |s| s.match?(reg) }
if non_domain_servers.any?
(Value['dns']['default-nameserver'] ||= []).concat(non_domain_servers).uniq!
end
end
rescue Exception => e
YAML.LOG('Error: Set default-nameserver Failed,【%s】' % [e.message])
end
begin
if '$custom_fallback_filter' == '1'
if !Value.dig('dns', 'fallback')
YAML.LOG('Error: Fallback-Filter Need fallback of DNS Been Setted, Ignore...')
elsif (filter_config = safe_load_yaml('/etc/openclash/custom/openclash_custom_fallback_filter.yaml'))
Value['dns']['fallback-filter'] = filter_config['fallback-filter']
else
YAML.LOG('Error: Unable To Parse Custom Fallback-Filter File, Ignore...')
end
end
rescue Exception => e
YAML.LOG('Error: Set fallback-filter Failed,【%s】' % [e.message])
end
end
# proxy-server-nameserver
threads << Thread.new do
begin
if enable_custom_dns
if (proxydns = safe_load_yaml('/tmp/yaml_config.proxynamedns.yaml')) && proxydns['proxy-server-nameserver']
(Value['dns']['proxy-server-nameserver'] ||= []).concat(proxydns['proxy-server-nameserver']).uniq!
end
end
rescue Exception => e
YAML.LOG('Error: Set proxy-server-nameserver Failed,【%s】' % [e.message])
end
end
# direct-nameserver
threads << Thread.new do
begin
if enable_custom_dns
if (directdns = safe_load_yaml('/tmp/yaml_config.directnamedns.yaml')) && directdns['direct-nameserver']
(Value['dns']['direct-nameserver'] ||= []).concat(directdns['direct-nameserver']).uniq!
end
end
rescue Exception => e
YAML.LOG('Error: Set direct-nameserver Failed,【%s】' % [e.message])
end
end
# nameserver-policy
threads << Thread.new do
begin
if custom_name_policy
if (policy = safe_load_yaml('/etc/openclash/custom/openclash_custom_domain_dns_policy.list'))
(Value['dns']['nameserver-policy'] ||= {}).merge!(policy)
end
end
rescue Exception => e
YAML.LOG('Error: Set Nameserver-Policy Failed,【%s】' % [e.message])
end
end
# proxy-server-nameserver-policy
threads << Thread.new do
begin
if custom_proxy_server_policy
if (policy = safe_load_yaml('/etc/openclash/custom/openclash_custom_proxy_server_dns_policy.list'))
(Value['dns']['proxy-server-nameserver-policy'] ||= {}).merge!(policy)
end
end
rescue Exception => e
YAML.LOG('Error: Set Proxy-Server-Nameserver-Policy Failed,【%s】' % [e.message])
end
end
# Fake-IP Filter
threads << Thread.new do
begin
if custom_fakeip_filter
Value['dns']['fake-ip-filter-mode'] = fake_ip_filter_mode
if fake_ip_mode == 'fake-ip'
merge_list_from_file(Value['dns'], 'fake-ip-filter', '/etc/openclash/custom/openclash_custom_fake_filter.list')
merge_list_from_file(Value['dns'], 'fake-ip-filter', '/tmp/yaml_openclash_fake_filter_include')
end
end
if fake_ip_mode == 'fake-ip' && (china_ip_route || china_ip6_route)
filter_mode = Value.dig('dns', 'fake-ip-filter-mode')
filters = Value.dig('dns', 'fake-ip-filter') || []
deleted_filters = filters.select { |f| f =~ /(geosite:?|rule-set:?).*(@cn|:cn|,cn|:china)/i }
if filter_mode == 'blacklist' || filter_mode.nil?
if !deleted_filters.any?
(Value['dns']['fake-ip-filter'] ||= []) << 'geosite:cn'
YAML.LOG('Tip: Because Need Ensure Bypassing IP Option Work, Added The Fake-IP-Filter Rule【geosite:cn】...')
end
else
if deleted_filters.any?
Value['dns']['fake-ip-filter'] -= deleted_filters
deleted_filters.each do |f|
YAML.LOG('Tip: Because Need Ensure Bypassing IP Option Work, Deleted The Fake-IP-Filter Rule【%s】...' % [f])
end
end
end
if filter_mode == 'rule'
(Value['dns']['fake-ip-filter'] ||= []).unshift('GEOSITE,cn,real-ip')
YAML.LOG('Tip: Because Need Ensure Bypassing IP Option Work, Added The Fake-IP-Filter Rule【GEOSITE,cn,real-ip】...')
end
end
rescue Exception => e
YAML.LOG('Error: Set Fake-IP-Filter Failed,【%s】' % [e.message])
end
end
# Custom Hosts
threads << Thread.new do
begin
if custom_host
if (hosts_content = safe_load_yaml('/etc/openclash/custom/openclash_custom_hosts.list')) && !hosts_content.empty?
Value['dns']['use-hosts'] = true
if hosts_content.is_a?(Hash) && hosts_content.key?('hosts')
(Value['hosts'] ||= {}).merge!(hosts_content['hosts'])
else
(Value['hosts'] ||= {}).merge!(hosts_content)
end
YAML.LOG('Warning: You May Need to Turn off The Rebinding Protection Option of Dnsmasq When Hosts Has Set a Reserved Address...')
end
end
rescue Exception => e
YAML.LOG('Error: Set Hosts Rules Failed,【%s】' % [e.message])
end
end
# Authentication
threads << Thread.new do
begin
if (auth_config = safe_load_yaml('/tmp/yaml_openclash_auth'))
Value['authentication'] = auth_config
end
rescue Exception => e
YAML.LOG('Error: Set authentication Failed,【%s】' % [e.message])
end
end
threads.each(&:join)
begin
threads.clear
fake_ip_mode = '$1'
secret = '$2'
controller_port = '$3'
redir_port = '$4'
enable_ipv6 = '$6' == '1'
http_port = '$7'
socks_port = '$8'
log_level = '$9'
mode = '${10}'
en_mode_tun = '$en_mode_tun'
stack_type = '$stack_type'
dns_listen_port = '${13}'
mixed_port = '${14}'
tproxy_port = '${15}'
dns_ipv6 = '${16}' == '1'
store_fake_ip = '${17}' == '1'
enable_sniffer = '${18}' == '1'
geodata_mode = '${19}' == '1'
geodata_loader = '${20}'
append_sniffer_config = '${21}' == '1'
interface_name = '${22}'
tcp_concurrent = '${23}' == '1'
add_default_from_dns = '${25}' == '1'
sniffer_parse_pure_ip = '${26}' == '1'
find_process_mode = '${27}'
fake_ip_range = '${28}'
ipv6_mode = '${29}'
unified_delay = '${31}' == '1'
respect_rules = '${32}' == '1'
fake_ip_filter_mode = '${33}'
routing_mark_setting = '${34}'
quic_gso = '${35}' == '1'
cors_origin = '${36}'
geo_custom_url = '${37}'
geoip_custom_url = '${38}'
geosite_custom_url = '${39}'
geoasn_custom_url = '${40}'
lgbm_auto_update = '${41}' == '1'
lgbm_custom_url = '${42}'
lgbm_update_interval = '${43}'
smart_collect = '${44}' == '1'
smart_collect_size = '${45}'
fake_ip_range6 = '${46}'
default_dashboard = '$default_dashboard'
yacd_type = '$yacd_type'
dashboard_type = '$dashboard_type'
# DNS Loop Check
if enable_redirect_dns != '2'
dns_options = ['nameserver', 'fallback', 'default-nameserver', 'proxy-server-nameserver', 'nameserver-policy', 'direct-nameserver', 'proxy-server-nameserver-policy']
dns_options.each do |option|
threads << Thread.new(option) do |opt|
begin
next unless Value['dns'].key?(opt) && !Value['dns'][opt].nil?
if opt != 'nameserver-policy' && opt != 'proxy-server-nameserver-policy'
original_size = Value['dns'][opt].size
Value['dns'][opt].reject! { |v| v.to_s.match?(/^system($|:\/\/)/) }
if Value['dns'][opt].size < original_size
YAML.LOG('Tip: Option【%s】is Setted【system】as DNS Server Which May Cause DNS Loop, Already Remove It...' % [opt])
end
else
Value['dns'][opt].each do |k, v|
if v.is_a?(Array)
original_size = v.size
v.reject! { |z| z.to_s.match?(/^system($|:\/\/)/) }
if v.empty?
Value['dns'][opt].delete(k)
YAML.LOG('Tip: Option【%s - %s】is Setted【system】as DNS Server Which May Cause DNS Loop, Already Remove It...' % [opt, k])
elsif v.size < original_size
YAML.LOG('Tip: Option【%s - %s】is Setted【system】as DNS Server Which May Cause DNS Loop, Already Remove It...' % [opt, k])
end
elsif v.to_s.match?(/^system($|:\/\/)/)
Value['dns'][opt].delete(k)
YAML.LOG('Tip: Option【%s - %s】is Setted【%s】as DNS Server Which May Cause DNS Loop, Already Remove It...' % [opt, k, v.to_s])
end
end
end
rescue Exception => e
YAML.LOG('Error: DNS Loop Check,【%s】' % [e.message])
enable_custom_dns = '$enable_custom_dns' == '1'
append_wan_dns = '$append_wan_dns' == '1'
custom_fakeip_filter = '$custom_fakeip_filter' == '1'
china_ip_route = '$china_ip_route' != '0'
china_ip6_route = '$china_ip6_route' != '0'
custom_name_policy = '$custom_name_policy' == '1'
custom_proxy_server_policy = '$custom_proxy_server_policy' == '1'
custom_host = '$custom_host' == '1'
enable_redirect_dns = '$enable_redirect_dns'
Value['dns'] ||= {}
threads = []
threads << Thread.new do
begin
Value['redir-port'] = redir_port.to_i
Value['tproxy-port'] = tproxy_port.to_i
Value['port'] = http_port.to_i
Value['socks-port'] = socks_port.to_i
Value['mixed-port'] = mixed_port.to_i
Value['mode'] = mode
Value['log-level'] = log_level if log_level != '0'
Value['allow-lan'] = true
Value['external-controller'] = '0.0.0.0:' + controller_port
Value['secret'] = secret
Value['bind-address'] = '*'
Value['external-ui'] = '/usr/share/openclash/ui'
Value['external-ui-name'] = default_dashboard
case default_dashboard
when 'dashboard'
if dashboard_type == 'Official'
Value['external-ui-url'] = 'https://codeload.github.com/ayanamist/clash-dashboard/zip/refs/heads/gh-pages'
else
Value['external-ui-url'] = 'https://codeload.github.com/MetaCubeX/Razord-meta/zip/refs/heads/gh-pages'
end
when 'yacd'
if yacd_type == 'Official'
Value['external-ui-url'] = 'https://codeload.github.com/haishanh/yacd/zip/refs/heads/gh-pages'
else
Value['external-ui-url'] = 'https://codeload.github.com/MetaCubeX/Yacd-meta/zip/refs/heads/gh-pages'
end
when 'metacubexd'
Value['external-ui-url'] = 'https://codeload.github.com/MetaCubeX/metacubexd/zip/refs/heads/gh-pages'
when 'zashboard'
Value['external-ui-url'] = 'https://codeload.github.com/Zephyruso/zashboard/zip/refs/heads/gh-pages-cdn-fonts'
end
if !Value.key?('keep-alive-interval') && !Value.key?('keep-alive-idle')
Value['keep-alive-interval'] = 15
Value['keep-alive-idle'] = 600
end
Value['ipv6'] = enable_ipv6
Value['interface-name'] = interface_name if interface_name != '0'
Value['geodata-mode'] = true if geodata_mode
Value['geodata-loader'] = geodata_loader if geodata_loader != '0'
Value['tcp-concurrent'] = true if tcp_concurrent
Value['unified-delay'] = true if unified_delay
Value['find-process-mode'] = find_process_mode if find_process_mode != '0'
(Value['experimental'] ||= {})['quic-go-disable-gso'] = true if quic_gso
if cors_origin != '0'
(Value['external-controller-cors'] ||= {})['allow-origins'] = [cors_origin]
Value['external-controller-cors']['allow-private-network'] = true
end
Value['lgbm-auto-update'] = true if lgbm_auto_update
if lgbm_auto_update
Value['lgbm-url'] = lgbm_custom_url.strip
Value['lgbm-update-interval'] = lgbm_update_interval.to_i
end
if smart_collect
(Value['profile'] ||= {})['smart-collector-size'] = smart_collect_size.to_f
end
Value['geox-url'] ||= {}
if geo_custom_url != '0'
Value['geox-url']['mmdb'] = geo_custom_url
end
if geoip_custom_url != '0'
Value['geox-url']['geoip'] = geoip_custom_url
end
if geosite_custom_url != '0'
Value['geox-url']['geosite'] = geosite_custom_url
end
if geoasn_custom_url != '0'
Value['geox-url']['asn'] = geoasn_custom_url
end
Value['dns']['enable'] = true
Value['dns']['ipv6'] = dns_ipv6
Value['ipv6'] = true if dns_ipv6
if fake_ip_mode == 'redir-host'
Value['dns']['enhanced-mode'] = 'redir-host'
Value['dns'].delete('fake-ip-range')
else
Value['dns']['enhanced-mode'] = 'fake-ip'
Value['dns']['fake-ip-range'] = fake_ip_range
if Value['dns']['ipv6']
Value['dns']['fake-ip-range6'] = fake_ip_range6
end
end
Value['dns']['listen'] = '0.0.0.0:' + dns_listen_port
Value['dns']['respect-rules'] = respect_rules
if enable_sniffer
sniffer_config = {
'enable' => true, 'override-destination' => true,
'sniff' => {'QUIC' => {'ports' => [443]}, 'TLS' => {'ports' => [443, 8443]}, 'HTTP' => {'ports' => [80, '8080-8880'], 'override-destination' => true}},
'force-domain' => ['+.netflix.com', '+.nflxvideo.net', '+.amazonaws.com', '+.media.dssott.com'],
'skip-domain' => ['Mijia Cloud', 'dlg.io.mi.com', '+.oray.com', '+.sunlogin.net', '+.push.apple.com']
}
sniffer_config['force-dns-mapping'] = true if fake_ip_mode == 'redir-host'
sniffer_config['parse-pure-ip'] = true if sniffer_parse_pure_ip
Value['sniffer'] = sniffer_config
if append_sniffer_config && (custom_sniffer = safe_load_yaml('/etc/openclash/custom/openclash_custom_sniffer.yaml'))
Value['sniffer'].merge!(custom_sniffer['sniffer']) if custom_sniffer && custom_sniffer['sniffer']
end
else
Value['sniffer']['enable'] = false if Value.key?('sniffer')
end
if en_mode_tun != '0' || ['2', '3'].include?(ipv6_mode)
Value['tun'] = {
'enable' => true, 'stack' => stack_type, 'device' => 'utun',
'dns-hijack' => ['127.0.0.1:53'], 'endpoint-independent-nat' => true,
'auto-route' => false, 'auto-detect-interface' => false,
'auto-redirect' => false, 'strict-route' => false, 'disable-icmp-forwarding' => false
}
Value['tun'].delete('iproute2-table-index')
else
Value.delete('tun')
end
Value.delete('iptables')
(Value['profile'] ||= {})['store-selected'] = true
Value['profile']['store-fake-ip'] = true if store_fake_ip
Value.delete('ebpf')
if routing_mark_setting == '0'
Value['routing-mark'] = 6666
else
Value.delete('routing-mark')
end
Value.delete('auto-redir')
(Value['ntp'] ||= {})['enable'] = true
Value['ntp']['server'] = 'time.apple.com' if !Value['ntp'].key?('server')
Value['ntp']['port'] = 123 if !Value['ntp'].key?('port')
Value['ntp']['interval'] = 30 if !Value['ntp'].key?('interval')
Value['ntp']['write-to-system'] = true if !Value['ntp'].key?('write-to-system')
rescue Exception => e
YAML.LOG_ERROR('Set General Failed,【%s】' % [e.message])
end
threads.each(&:join)
end
if Value.dig('dns', 'nameserver').to_a.empty?
YAML.LOG('Tip: Detected That The nameserver DNS Option Has No Server Set, Starting To Complete...')
Value['dns']['nameserver'] = ['114.114.114.114', '119.29.29.29', '8.8.8.8', '1.1.1.1']
Value['dns']['fallback'] ||= ['https://dns.cloudflare.com/dns-query', 'https://dns.google/dns-query']
end
threads << Thread.new do
begin
if enable_custom_dns || append_wan_dns
if (namedns_config = safe_load_yaml('/tmp/yaml_config.namedns.yaml')) && namedns_config['nameserver']
if enable_custom_dns
Value['dns']['nameserver'] = namedns_config['nameserver'].uniq
elsif append_wan_dns
(Value['dns']['nameserver'] ||= []).concat(namedns_config['nameserver']).uniq!
end
if Value['dns'].key?('default-nameserver') && Value['dns']['default-nameserver'].to_a.empty?
YAML.LOG('Tip: Detected That The default-nameserver DNS Option Has No Server Set, Starting To Complete...')
Value['dns']['default-nameserver'] = ['114.114.114.114', '119.29.29.29', '8.8.8.8', '1.1.1.1']
if enable_custom_dns && (falldns_config = safe_load_yaml('/tmp/yaml_config.falldns.yaml')) && falldns_config['fallback']
Value['dns']['fallback'] = falldns_config['fallback'].uniq
end
elsif enable_custom_dns
YAML.LOG_ERROR('Nameserver Option Must Be Setted, Stop Customing DNS Servers')
end
end
rescue Exception => e
YAML.LOG_ERROR('Set Custom DNS Failed,【%s】' % [e.message])
end
begin
if enable_custom_dns
if (defaultdns_config = safe_load_yaml('/tmp/yaml_config.defaultdns.yaml')) && defaultdns_config['default-nameserver']
Value['dns']['default-nameserver'] = defaultdns_config['default-nameserver'].uniq
end
end
if add_default_from_dns
reg = /^dhcp:\/\/|^system($|:\/\/)|([0-9a-zA-Z-]{1,}\.)+([a-zA-Z]{2,})/
servers_to_check = Value.dig('dns', 'nameserver').to_a | Value.dig('dns', 'fallback').to_a
non_domain_servers = servers_to_check.reject { |s| s.match?(reg) }
if non_domain_servers.any?
(Value['dns']['default-nameserver'] ||= []).concat(non_domain_servers).uniq!
end
end
rescue Exception => e
YAML.LOG_ERROR('Set default-nameserver Failed,【%s】' % [e.message])
end
begin
if '$custom_fallback_filter' == '1'
if !Value.dig('dns', 'fallback')
YAML.LOG_ERROR('Fallback-Filter Need fallback of DNS Been Setted, Ignore...')
elsif (filter_config = safe_load_yaml('/etc/openclash/custom/openclash_custom_fallback_filter.yaml'))
Value['dns']['fallback-filter'] = filter_config['fallback-filter']
else
YAML.LOG_ERROR('Unable To Parse Custom Fallback-Filter File, Ignore...')
end
end
rescue Exception => e
YAML.LOG_ERROR('Set fallback-filter Failed,【%s】' % [e.message])
end
end
# proxy-server-nameserver
local_exclude = (%x{ls -l /sys/class/net/ |awk '{print \$9}' 2>&1}.each_line.map(&:strip) + ['h3=', 'skip-cert-verify=', 'ecs=', 'ecs-override=', 'disable-ipv6=', 'disable-ipv4=', 'disable-qtype-'] + ['utun', 'tailscale0', 'docker0', 'tun163', 'br-lan', 'mihomo']).uniq.join('|')
non_domain_reg = /^dhcp:\/\/|^system($|:\/\/)|([0-9a-zA-Z-]{1,}\.)+([a-zA-Z]{2,})/
proxied_server_reg = /^[^#&]+#(?:(?:#{local_exclude})[^&]*&)*(?:(?!(?:#{local_exclude}))[^&]+)/
servers_to_check = Value.dig('dns', 'nameserver').to_a | Value.dig('dns', 'fallback').to_a | Value.dig('dns', 'default-nameserver').to_a
default_proxy_servers = servers_to_check.reject { |s| s.match?(non_domain_reg) }
if ! default_proxy_servers.any? || default_proxy_servers.all? { |x| x.match?(proxied_server_reg) }
default_proxy_servers = ['114.114.114.114', '119.29.29.29', '8.8.8.8', '1.1.1.1']
threads << Thread.new do
begin
if enable_custom_dns
if (proxydns = safe_load_yaml('/tmp/yaml_config.proxynamedns.yaml')) && proxydns['proxy-server-nameserver']
(Value['dns']['proxy-server-nameserver'] ||= []).concat(proxydns['proxy-server-nameserver']).uniq!
end
end
rescue Exception => e
YAML.LOG_ERROR('Set proxy-server-nameserver Failed,【%s】' % [e.message])
end
end
proxy_server_nameserver_policy = Value.dig('dns', 'proxy-server-nameserver-policy') && !Value['dns']['proxy-server-nameserver-policy'].empty?
if Value.dig('dns', 'proxy-server-nameserver').to_a.empty?
all_ns_proxied = Value.dig('dns', 'nameserver').to_a.all? { |x| x.match?(proxied_server_reg) }
if respect_rules || Value.dig('dns', 'respect-rules').to_s == 'true' || all_ns_proxied || proxy_server_nameserver_policy
Value['dns']['proxy-server-nameserver'] = default_proxy_servers
if all_ns_proxied
YAML.LOG('Tip: Nameserver Option Maybe All Setted The Proxy Option, Auto Set Proxy-server-nameserver Option to【%s】For Avoiding Proxies Server Resolve Loop...' % [default_proxy_servers.join(', ')])
elsif proxy_server_nameserver_policy
YAML.LOG('Tip:【Proxy-server-nameserver-policy】Need Proxy-server-nameserver Option Must Be Setted, Auto Set to【%s】' % [default_proxy_servers.join(', ')])
else
YAML.LOG('Tip:【Respect-rules】Need Proxy-server-nameserver Option Must Be Setted, Auto Set to【%s】' % [default_proxy_servers.join(', ')])
# direct-nameserver
threads << Thread.new do
begin
if enable_custom_dns
if (directdns = safe_load_yaml('/tmp/yaml_config.directnamedns.yaml')) && directdns['direct-nameserver']
(Value['dns']['direct-nameserver'] ||= []).concat(directdns['direct-nameserver']).uniq!
end
end
rescue Exception => e
YAML.LOG_ERROR('Set direct-nameserver Failed,【%s】' % [e.message])
end
end
# nameserver-policy
threads << Thread.new do
begin
if custom_name_policy
if (policy = safe_load_yaml('/etc/openclash/custom/openclash_custom_domain_dns_policy.list'))
(Value['dns']['nameserver-policy'] ||= {}).merge!(policy)
end
end
rescue Exception => e
YAML.LOG_ERROR('Set Nameserver-Policy Failed,【%s】' % [e.message])
end
end
# proxy-server-nameserver-policy
threads << Thread.new do
begin
if custom_proxy_server_policy
if (policy = safe_load_yaml('/etc/openclash/custom/openclash_custom_proxy_server_dns_policy.list'))
(Value['dns']['proxy-server-nameserver-policy'] ||= {}).merge!(policy)
end
end
rescue Exception => e
YAML.LOG_ERROR('Set Proxy-Server-Nameserver-Policy Failed,【%s】' % [e.message])
end
end
# Fake-IP Filter
threads << Thread.new do
begin
if custom_fakeip_filter
Value['dns']['fake-ip-filter-mode'] = fake_ip_filter_mode
if fake_ip_mode == 'fake-ip'
merge_list_from_file(Value['dns'], 'fake-ip-filter', '/etc/openclash/custom/openclash_custom_fake_filter.list')
merge_list_from_file(Value['dns'], 'fake-ip-filter', '/tmp/yaml_openclash_fake_filter_include')
end
end
if fake_ip_mode == 'fake-ip' && (china_ip_route || china_ip6_route)
filter_mode = Value.dig('dns', 'fake-ip-filter-mode')
filters = Value.dig('dns', 'fake-ip-filter') || []
deleted_filters = filters.select { |f| f =~ /(geosite:?|rule-set:?).*(@cn|:cn|,cn|:china)/i }
if filter_mode == 'blacklist' || filter_mode.nil?
if !deleted_filters.any?
(Value['dns']['fake-ip-filter'] ||= []) << 'geosite:cn'
YAML.LOG_TIP('Because Need Ensure Bypassing IP Option Work, Added The Fake-IP-Filter Rule【geosite:cn】...')
end
else
if deleted_filters.any?
Value['dns']['fake-ip-filter'] -= deleted_filters
deleted_filters.each do |f|
YAML.LOG_TIP('Because Need Ensure Bypassing IP Option Work, Deleted The Fake-IP-Filter Rule【%s】...' % [f])
end
end
end
if filter_mode == 'rule'
(Value['dns']['fake-ip-filter'] ||= []).unshift('GEOSITE,cn,real-ip')
YAML.LOG_TIP('Because Need Ensure Bypassing IP Option Work, Added The Fake-IP-Filter Rule【GEOSITE,cn,real-ip】...')
end
end
rescue Exception => e
YAML.LOG_ERROR('Set Fake-IP-Filter Failed,【%s】' % [e.message])
end
end
# Custom Hosts
threads << Thread.new do
begin
if custom_host
if (hosts_content = safe_load_yaml('/etc/openclash/custom/openclash_custom_hosts.list')) && !hosts_content.empty?
Value['dns']['use-hosts'] = true
if hosts_content.is_a?(Hash) && hosts_content.key?('hosts')
(Value['hosts'] ||= {}).merge!(hosts_content['hosts'])
else
(Value['hosts'] ||= {}).merge!(hosts_content)
end
YAML.LOG_WARN('You May Need to Turn off The Rebinding Protection Option of Dnsmasq When Hosts Has Set a Reserved Address...')
end
end
rescue Exception => e
YAML.LOG_ERROR('Set Hosts Rules Failed,【%s】' % [e.message])
end
end
# Authentication
threads << Thread.new do
begin
if (auth_config = safe_load_yaml('/tmp/yaml_openclash_auth'))
Value['authentication'] = auth_config
end
rescue Exception => e
YAML.LOG_ERROR('Set authentication Failed,【%s】' % [e.message])
end
end
threads.each(&:join)
begin
threads.clear
# DNS Loop Check
if enable_redirect_dns == '1'
dns_options = ['nameserver', 'fallback', 'default-nameserver', 'proxy-server-nameserver', 'nameserver-policy', 'direct-nameserver', 'proxy-server-nameserver-policy']
dns_options.each do |option|
threads << Thread.new(option) do |opt|
begin
next unless Value['dns'].key?(opt) && !Value['dns'][opt].nil?
if opt != 'nameserver-policy' && opt != 'proxy-server-nameserver-policy'
original_size = Value['dns'][opt].size
Value['dns'][opt].reject! { |v| v.to_s.match?(/^system($|:\/\/)/) }
if Value['dns'][opt].size < original_size
YAML.LOG_TIP('Option【%s】is Setted【system】as DNS Server Which May Cause DNS Loop, Already Remove It...' % [opt])
end
else
Value['dns'][opt].each do |k, v|
if v.is_a?(Array)
original_size = v.size
v.reject! { |z| z.to_s.match?(/^system($|:\/\/)/) }
if v.empty?
Value['dns'][opt].delete(k)
YAML.LOG_TIP('Option【%s - %s】is Setted【system】as DNS Server Which May Cause DNS Loop, Already Remove It...' % [opt, k])
elsif v.size < original_size
YAML.LOG_TIP('Option【%s - %s】is Setted【system】as DNS Server Which May Cause DNS Loop, Already Remove It...' % [opt, k])
end
elsif v.to_s.match?(/^system($|:\/\/)/)
Value['dns'][opt].delete(k)
YAML.LOG_TIP('Option【%s - %s】is Setted【%s】as DNS Server Which May Cause DNS Loop, Already Remove It...' % [opt, k, v.to_s])
end
end
end
rescue Exception => e
YAML.LOG_ERROR('DNS Loop Check,【%s】' % [e.message])
end
end
end
threads.each(&:join)
end
if Value.dig('dns', 'nameserver').to_a.empty?
YAML.LOG_TIP('Detected That The nameserver DNS Option Has No Server Set, Starting To Complete...')
Value['dns']['nameserver'] = ['114.114.114.114', '119.29.29.29', '8.8.8.8', '1.1.1.1']
Value['dns']['fallback'] ||= ['https://dns.cloudflare.com/dns-query', 'https://dns.google/dns-query']
end
if Value['dns'].key?('default-nameserver') && Value['dns']['default-nameserver'].to_a.empty?
YAML.LOG_TIP('Detected That The default-nameserver DNS Option Has No Server Set, Starting To Complete...')
Value['dns']['default-nameserver'] = ['114.114.114.114', '119.29.29.29', '8.8.8.8', '1.1.1.1']
end
# proxy-server-nameserver
local_exclude = (%x{ls -l /sys/class/net/ |awk '{print \$9}' 2>&1}.each_line.map(&:strip) + ['h3=', 'skip-cert-verify=', 'ecs=', 'ecs-override=', 'disable-ipv6=', 'disable-ipv4=', 'disable-qtype-', 'disable-reuse='] + ['utun', 'tailscale0', 'docker0', 'tun163', 'br-lan', 'mihomo']).uniq.join('|')
non_domain_reg = /^dhcp:\/\/|^system($|:\/\/)|([0-9a-zA-Z-]{1,}\.)+([a-zA-Z]{2,})/
proxied_server_reg = /^[^#&]+#(?:(?:#{local_exclude})[^&]*&)*(?:(?!(?:#{local_exclude}))[^&]+)/
servers_to_check = Value.dig('dns', 'nameserver').to_a | Value.dig('dns', 'fallback').to_a | Value.dig('dns', 'default-nameserver').to_a
default_proxy_servers = servers_to_check.reject { |s| s.match?(non_domain_reg) }
if ! default_proxy_servers.any? || default_proxy_servers.all? { |x| x.match?(proxied_server_reg) }
default_proxy_servers = ['114.114.114.114', '119.29.29.29', '8.8.8.8', '1.1.1.1']
end
proxy_server_nameserver_policy = Value.dig('dns', 'proxy-server-nameserver-policy') && !Value['dns']['proxy-server-nameserver-policy'].empty?
if Value.dig('dns', 'proxy-server-nameserver').to_a.empty?
all_ns_proxied = Value.dig('dns', 'nameserver').to_a.all? { |x| x.match?(proxied_server_reg) }
if respect_rules || Value.dig('dns', 'respect-rules').to_s == 'true' || all_ns_proxied || proxy_server_nameserver_policy
Value['dns']['proxy-server-nameserver'] = default_proxy_servers
if all_ns_proxied
YAML.LOG_TIP('Nameserver Option Maybe All Setted The Proxy Option, Auto Set Proxy-server-nameserver Option to【%s】For Avoiding Proxies Server Resolve Loop...' % [default_proxy_servers.join(', ')])
elsif proxy_server_nameserver_policy
YAML.LOG_TIP('【Proxy-server-nameserver-policy】Need Proxy-server-nameserver Option Must Be Setted, Auto Set to【%s】' % [default_proxy_servers.join(', ')])
else
YAML.LOG_TIP('【Respect-rules】Need Proxy-server-nameserver Option Must Be Setted, Auto Set to【%s】' % [default_proxy_servers.join(', ')])
end
end
else
all_psn_proxied = Value.dig('dns', 'proxy-server-nameserver').to_a.all? { |x| x.match?(proxied_server_reg) }
if all_psn_proxied
(Value['dns']['proxy-server-nameserver'] ||= []).concat(default_proxy_servers).uniq!
YAML.LOG_TIP('Proxy-server-nameserver Option Maybe All Setted The Proxy Option, Auto Set Proxy-server-nameserver Option to【%s】For Avoiding Proxies Server Resolve Loop...' % [default_proxy_servers.join(', ')])
end
end
else
all_psn_proxied = Value.dig('dns', 'proxy-server-nameserver').to_a.all? { |x| x.match?(proxied_server_reg) }
if all_psn_proxied
(Value['dns']['proxy-server-nameserver'] ||= []).concat(default_proxy_servers).uniq!
YAML.LOG('Tip: Proxy-server-nameserver Option Maybe All Setted The Proxy Option, Auto Set Proxy-server-nameserver Option to【%s】For Avoiding Proxies Server Resolve Loop...' % [default_proxy_servers.join(', ')])
end
rescue Exception => e
YAML.LOG_ERROR('Config File params checked Failed,【%s】' % [e.message])
end
rescue Exception => e
YAML.LOG('Error: Config File Overwrite Failed,【%s】' % [e.message])
YAML.LOG_ERROR('Config File Overwrite Failed,【%s】' % [e.message])
ensure
File.open(config_file, 'w') { |f| YAML.dump(Value, f) }
end
@@ -13,13 +13,9 @@ del_lock() {
rm -rf "/tmp/lock/openclash_groups_get.lock"
}
CFG_FILE="/etc/config/openclash"
other_group_file="/tmp/yaml_other_group.yaml"
servers_update=$(uci_get_config "servers_update")
servers_if_update=$(uci_get_config "servers_if_update")
CONFIG_FILE=$(uci_get_config "config_path")
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
UPDATE_CONFIG_FILE=$(uci_get_config "config_update_path")
UPDATE_CONFIG_FILE=$1
UPDATE_CONFIG_NAME=$(echo "$UPDATE_CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
LOG_FILE="/tmp/openclash.log"
set_lock
@@ -45,95 +41,36 @@ if [ -z "$CONFIG_NAME" ]; then
CONFIG_NAME="config.yaml"
fi
BACKUP_FILE="/etc/openclash/backup/$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)"
if [ ! -s "$CONFIG_FILE" ] && [ ! -s "$BACKUP_FILE" ]; then
if [ ! -s "$CONFIG_FILE" ]; then
del_lock
exit 0
elif [ ! -s "$CONFIG_FILE" ] && [ -s "$BACKUP_FILE" ]; then
mv "$BACKUP_FILE" "$CONFIG_FILE"
fi
LOG_OUT "Start Getting【$CONFIG_NAME】Groups Setting..."
LOG_OUT "Deleting Old Configuration..."
/usr/share/openclash/yml_groups_name_get.sh
if [ $? -ne 0 ]; then
LOG_OUT "Read Error, Config File【$CONFIG_NAME】Abnormal!"
uci -q commit openclash
SLOG_CLEAN
del_lock
exit 0
fi
#判断当前配置文件是否有策略组信息
cfg_group_name()
del_options()
{
local section="$1"
local config
config_get "config" "$section" "config" ""
if [ -z "$config" ]; then
return
if [ "$config" = "$CONFIG_NAME" ]; then
uci -q delete openclash."$section"
fi
[ "$config" = "$CONFIG_NAME" ] || [ "$config" = "all" ] && {
config_group_exist=1
}
}
#删除不必要的配置
cfg_delete()
{
LOG_OUT "Deleting Old Configuration..."
#删除策略组
group_num=$(grep "^config groups$" "$CFG_FILE" |wc -l)
for ((i=$group_num;i>=0;i--))
do
if [ "$(uci -q get openclash.@groups["$i"].config)" = "$CONFIG_NAME" ]; then
uci -q delete openclash.@groups["$i"]
uci -q commit openclash
fi
done
#删除启用的节点
server_num=$(grep "^config servers$" "$CFG_FILE" |wc -l)
for ((i=$server_num;i>=0;i--))
do
if [ "$(uci -q get openclash.@servers["$i"].config)" = "$CONFIG_NAME" ]; then
if [ "$(uci -q get openclash.@servers["$i"].enabled)" = "1" ] && [ "$(uci -q get openclash.@servers["$i"].manual)" = "0" ]; then
uci -q delete openclash.@servers["$i"]
uci -q commit openclash
fi
fi
done
#删除启用的代理集
provider_num=$(grep "^config proxy-provider$" "$CFG_FILE" 2>/dev/null |wc -l)
for ((i=$provider_num;i>=0;i--))
do
if [ "$(uci -q get openclash.@proxy-provider["$i"].config)" = "$CONFIG_NAME" ]; then
if [ "$(uci -q get openclash.@proxy-provider["$i"].enabled)" = "1" ] && [ "$(uci -q get openclash.@proxy-provider["$i"].manual)" = "0" ]; then
uci -q delete openclash.@proxy-provider["$i"]
uci -q commit openclash
fi
fi
done
}
config_load "openclash"
config_foreach cfg_group_name "groups"
if [ "$servers_if_update" -eq 1 ] && [ "$servers_update" -eq 1 ] && [ "$config_group_exist" -eq 1 ]; then
/usr/share/openclash/yml_proxys_get.sh
del_lock
exit 0
fi
cfg_delete
config_foreach del_options "groups"
config_foreach del_options "servers"
config_foreach del_options "proxy-provider"
uci -q commit openclash
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
begin
Value = YAML.load_file('$CONFIG_FILE');
rescue Exception => e
YAML.LOG('Error: Load File Failed,【' + e.message + '】');
YAML.LOG_ERROR('Load File Failed,【' + e.message + '】');
end;
threads_g = [];
@@ -148,7 +85,7 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
proxy-groups = [];
end;
Value_1 = File.readlines('/tmp/Proxy_Group').map!{|x| x.strip};
CONFIG_GROUP = (['DIRECT', 'REJECT', 'GLOBAL', 'REJECT-DROP', 'PASS', 'COMPATIBLE'] + (Value['proxy-groups']&.map { |x| x['name'] } || [])).uniq;
Value['proxy-groups'].each_with_index do |x, index|
uci_name_tmp << %x{uci -q add openclash groups 2>&1}.chomp
queue.push(nil)
@@ -181,8 +118,6 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
uci_commands << uci_set + 'config=\"' + '${CONFIG_NAME}' + '\"'
#old_name
uci_commands << uci_set + 'old_name=\"' + x['name'] + '\"'
#old_name_cfg
uci_commands << uci_set + 'old_name_cfg=\"' + x['name'] + '\"'
};
threads_g << Thread.new {
@@ -274,7 +209,7 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
if x.key?('proxies') then
x['proxies'].each{
|y|
if Value_1.include?(y) then
if CONFIG_GROUP.include?(y) then
uci_commands << uci_add + 'other_group=\"^' + y.to_s + '$\"'
end
}
@@ -289,7 +224,7 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
};
threads_g.each(&:join);
rescue Exception => e
YAML.LOG('Error: Resolve Groups Failed,【${CONFIG_NAME} - ' + x['type'] + ' - ' + x['name'] + ': ' + e.message + '】');
YAML.LOG_ERROR('Resolve Groups Failed,【${CONFIG_NAME} - ' + x['type'] + ' - ' + x['name'] + ': ' + e.message + '】');
ensure
queue.pop
end;
@@ -314,5 +249,5 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
system('rm -rf /tmp/yaml_other_group.yaml 2>/dev/null');
" 2>/dev/null >> $LOG_FILE
/usr/share/openclash/yml_proxys_get.sh
/usr/share/openclash/yml_proxys_get.sh "$CONFIG_FILE" >/dev/null 2>&1
del_lock
@@ -1,61 +0,0 @@
#!/bin/bash
. /lib/functions.sh
set_lock() {
exec 882>"/tmp/lock/openclash_name_ch.lock" 2>/dev/null
flock -x 882 2>/dev/null
}
del_lock() {
flock -u 882 2>/dev/null
rm -rf "/tmp/lock/openclash_name_ch.lock"
}
cfg_groups_set()
{
CFG_FILE="/etc/config/openclash"
local section="$1"
local name old_name_cfg old_name
config_get "name" "$section" "name" ""
config_get "old_name_cfg" "$section" "old_name_cfg" ""
config_get "old_name" "$section" "old_name" ""
if [ -z "$name" ]; then
return
fi
if [ -z "$old_name_cfg" ]; then
uci -q set openclash."$section".old_name_cfg="$name"
uci -q commit openclash
fi
if [ -z "$old_name" ]; then
uci -q set openclash."$section".old_name="$name"
uci -q commit openclash
fi
#名字变化时处理配置文件
if [ "$name" != "$old_name_cfg" ] && [ ! -z "$old_name_cfg" ]; then
convert_name=$(echo "$name" | sed 's/\//\\\//g' 2>/dev/null)
convert_old_name_cfg=$(echo "$old_name_cfg" | sed 's/\//\\\//g' 2>/dev/null)
sed -i "s/old_name_cfg '\(\^*\)${convert_old_name_cfg}\(\$*\)'/old_name_cfg '\1${convert_name}\2'/g" $CFG_FILE 2>/dev/null
sed -i "s/groups '\(\^*\)${convert_old_name_cfg}\(\$*\)'/groups '\1${convert_name}\2'/g" $CFG_FILE 2>/dev/null
sed -i "s/option group '\(\^*\)${convert_old_name_cfg}\(\$*\)'/option group '\1${convert_name}\2'/g" $CFG_FILE 2>/dev/null
sed -i "s/option specific_group '\(\^*\)${convert_old_name_cfg}\(\$*\)'/option specific_group '\1${convert_name}\2'/g" $CFG_FILE 2>/dev/null
sed -i "s/other_group '\(\^*\)${convert_old_name_cfg}\(\$*\)'/other_group '\1${convert_name}\2'/g" $CFG_FILE 2>/dev/null
sed -i "s/new_servers_group '\(\^*\)${convert_old_name_cfg}\(\$*\)'/new_servers_group '\1${convert_name}\2'/g" $CFG_FILE 2>/dev/null
sed -i "s/dialer_proxy '\(\^*\)${convert_old_name_cfg}\(\$*\)'/dialer_proxy '\1${convert_name}\2'/g" $CFG_FILE
#第三方规则处理
OTHER_RULE_NAMES=("GlobalTV" "AsianTV" "MainlandTV" "Proxy" "Youtube" "Bilibili" "Bahamut" "HBOMax" "Pornhub" "Apple" "GoogleFCM" "Scholar" "Microsoft" "Netflix" "Disney Plus" "Spotify" "Steam" "TikTok" "Speedtest" "Telegram" "PayPal" "Netease_Music" "AdBlock" "Domestic" "Others" "miHoYo" "AI_Suite" "AppleTV" "Crypto" "Discord" "HTTPDNS")
for i in ${OTHER_RULE_NAMES[@]}; do
sed -i "s/option ${i} \'${convert_old_name_cfg}\'/option ${i} \'${convert_name}\'/g" $CFG_FILE 2>/dev/null
done 2>/dev/null
config_load "openclash"
fi
}
set_lock
config_load "openclash"
config_foreach cfg_groups_set "groups"
del_lock
@@ -1,37 +0,0 @@
#!/bin/sh
. /usr/share/openclash/ruby.sh
. /usr/share/openclash/uci.sh
CFG_FILE=$(uci_get_config "config_path")
UPDATE_CONFIG_FILE=$(uci_get_config "config_update_path")
if [ ! -z "$UPDATE_CONFIG_FILE" ]; then
CFG_FILE="$UPDATE_CONFIG_FILE"
fi
if [ -z "$CFG_FILE" ]; then
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
rm -rf "/tmp/Proxy_Group" 2>/dev/null
ruby_read_hash_arr "$CFG_FILE" "['proxy-groups']" "['name']" >/tmp/Proxy_Group 2>&1
if [ -f "/tmp/Proxy_Group" ]; then
echo 'DIRECT' >>/tmp/Proxy_Group
echo 'REJECT' >>/tmp/Proxy_Group
echo 'REJECT-DROP' >>/tmp/Proxy_Group
echo 'PASS' >>/tmp/Proxy_Group
echo 'GLOBAL' >>/tmp/Proxy_Group
else
return 1
fi
else
return 1
fi
@@ -16,13 +16,12 @@ del_lock() {
set_lock
GROUP_FILE="/tmp/yaml_groups.yaml"
CFG_FILE="/etc/config/openclash"
servers_update=$(uci_get_config "servers_update")
CONFIG_FILE=$(uci_get_config "config_path")
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
UPDATE_CONFIG_FILE=$(uci_get_config "config_update_path")
UPDATE_CONFIG_FILE=$1
UPDATE_CONFIG_NAME=$(echo "$UPDATE_CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
if [ -n "$UPDATE_CONFIG_FILE" ]; then
if [ ! -z "$UPDATE_CONFIG_FILE" ]; then
CONFIG_FILE="$UPDATE_CONFIG_FILE"
CONFIG_NAME="$UPDATE_CONFIG_NAME"
fi
@@ -82,10 +81,6 @@ yml_servers_add()
if [ -z "$4" ]; then
config_list_foreach "$section" "groups" set_groups "$name" "$2"
fi
if [ -n "$if_game_group" ] && [ -z "$(ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "Value = YAML.load_file('$CONFIG_FILE'); Value['proxies'].each{|x| if x['name'].eql?('$name') then puts x['name'] end}" 2>/dev/null)" ]; then
/usr/share/openclash/yml_proxys_set.sh "$name" "proxy"
fi
fi
}
@@ -172,7 +167,7 @@ set_proxy_provider()
if [ -n "$config" ] && [ "$config" != "$CONFIG_NAME" ] && [ "$config" != "all" ]; then
return
fi
fi
if [ "$enabled" = "0" ]; then
return
@@ -180,10 +175,6 @@ set_proxy_provider()
if [ -z "$3" ]; then
config_list_foreach "$section" "groups" set_provider_groups "$name" "$2"
fi
if [ -n "$if_game_group" ] && [ -z "$(ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "Value = YAML.load_file('$CONFIG_FILE'); Value['proxy-providers'].keys.each{|x| if x.eql?('$name') then puts x end}" 2>/dev/null)" ]; then
/usr/share/openclash/yml_proxys_set.sh "$name" "proxy-provider"
fi
fi
}
@@ -207,7 +198,6 @@ set_provider_groups()
#创建策略组
yml_groups_set()
{
local section="$1"
local enabled config type name disable_udp strategy old_name test_url test_interval tolerance policy_filter uselightgbm collectdata policy_priority other_parameters icon
config_get_bool "enabled" "$section" "enabled" "1"
@@ -231,10 +221,6 @@ yml_groups_set()
return
fi
if [ -n "$if_game_group" ] && [ "$if_game_group" != "$name" ]; then
return
fi
if [ -n "$config" ] && [ "$config" != "$CONFIG_NAME" ] && [ "$config" != "all" ]; then
return
fi
@@ -247,28 +233,12 @@ yml_groups_set()
return
fi
#游戏策略组存在时判断节点是否存在
if [ -n "$if_game_group" ] && [ -n "$(grep "^$if_game_group$" /tmp/Proxy_Group)" ]; then
config_foreach yml_servers_add "servers" "$name" "$type" "check" #加入服务器节点
config_foreach set_proxy_provider "proxy-provider" "$name" "check" #加入代理集
return
fi
LOG_OUT "Start Writing【$CONFIG_NAME - $type - $name】Group To Config File..."
echo " - name: $name" >>$GROUP_FILE
echo " type: $type" >>$GROUP_FILE
echo " proxies: $name" >>$GROUP_FILE
#名字变化时处理规则部分
if [ "$name" != "$old_name" ] && [ -n "$old_name" ]; then
sed -i "s/,${old_name}/,${name}#delete_/g" "$CONFIG_FILE" 2>/dev/null
sed -i "s/: \"${old_name}\"/: \"${name}#delete_\"/g" "$CONFIG_FILE" 2>/dev/null
sed -i "s/return \"${old_name}\"$/return \"${name}#delete_\"/g" "$CONFIG_FILE" 2>/dev/null
sed -i "s/old_name \'${old_name}\'/old_name \'${name}\'/g" "$CFG_FILE" 2>/dev/null
config_load "openclash"
fi
set_group=0
set_proxy_provider=0
@@ -350,28 +320,13 @@ yml_groups_set()
fi
}
create_config=$(uci_get_config "create_config")
servers_if_update=$(uci_get_config "servers_if_update")
if_game_group="$1"
if [ "$create_config" = "0" ] || [ "$servers_if_update" = "1" ] || [ -n "$if_game_group" ]; then
/usr/share/openclash/yml_groups_name_get.sh
if [ $? -ne 0 ]; then
LOG_OUT "Error: Config File【$CONFIG_NAME】Unable To Parse, Please Choose One-key Function To Create Config File..."
uci -q commit openclash
SLOG_CLEAN
del_lock
exit 0
else
if [ -z "$if_game_group" ]; then
echo "proxy-groups:" >$GROUP_FILE
fi
config_load "openclash"
config_foreach yml_groups_set "groups"
sed -i "s/#delete_//g" "$CONFIG_FILE" 2>/dev/null
fi
fi
echo "proxy-groups:" >$GROUP_FILE
config_load "openclash"
config_foreach yml_groups_set "groups"
sed -i "s/#delete_//g" "$CONFIG_FILE" 2>/dev/null
/usr/share/openclash/yml_proxys_set.sh "$CONFIG_FILE" >/dev/null 2>&1
del_lock
if [ -z "$if_game_group" ]; then
/usr/share/openclash/yml_proxys_set.sh
fi
@@ -15,7 +15,7 @@ del_lock() {
CONFIG_FILE=$(uci_get_config "config_path")
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
UPDATE_CONFIG_FILE=$(uci_get_config "config_update_path")
UPDATE_CONFIG_FILE=$1
UPDATE_CONFIG_NAME=$(echo "$UPDATE_CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
LOG_FILE="/tmp/openclash.log"
set_lock
@@ -41,115 +41,17 @@ if [ -z "$CONFIG_NAME" ]; then
CONFIG_NAME="config.yaml"
fi
BACKUP_FILE="/etc/openclash/backup/$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)"
if [ ! -s "$CONFIG_FILE" ] && [ ! -s "$BACKUP_FILE" ]; then
if [ ! -s "$CONFIG_FILE" ]; then
del_lock
exit 0
elif [ ! -s "$CONFIG_FILE" ] && [ -s "$BACKUP_FILE" ]; then
mv "$BACKUP_FILE" "$CONFIG_FILE"
fi
CFG_FILE="/etc/config/openclash"
match_servers="/tmp/match_servers.list"
match_provider="/tmp/match_provider.list"
servers_update=$(uci_get_config "servers_update")
servers_if_update=$(uci_get_config "servers_if_update")
cfg_new_servers_groups_check()
{
if [ -z "$1" ]; then
return
fi
config_foreach cfg_group_name "groups" "$1"
}
cfg_group_name()
{
local section="$1"
local name config
config_get "name" "$section" "name" ""
config_get "config" "$section" "config" ""
if [ -z "$config" ]; then
return
fi
if [ "$config" != "$CONFIG_NAME" ] && [ "$config" != "all" ]; then
return
fi
if [ -z "$name" ]; then
return
fi
if [ "$name" = "$2" ]; then
if [ -z "$new_server_add_group" ]; then
new_server_add_group="$name"
else
new_server_add_group="$new_server_add_group|||$name"
fi
fi
}
#判断当前配置文件策略组信息是否包含指定策略组
config_load "openclash"
config_list_foreach "config" "new_servers_group" cfg_new_servers_groups_check
if [ "$(uci_get_config "new_servers_group")" = "all" ]; then
if [ -z "$new_server_add_group" ]; then
new_server_add_group="all"
else
new_server_add_group="all|||$new_server_add_group"
fi
fi
yml_provider_name_get()
{
local section="$1"
local name config
config_get "name" "$section" "name" ""
config_get "config" "$section" "config" ""
if [ -n "$name" ] && [ "$config" = "$CONFIG_NAME" ]; then
echo "$provider_nums.$name" >>"$match_provider"
fi
provider_nums=$(( $provider_nums + 1 ))
}
yml_servers_name_get()
{
local section="$1"
local name config
config_get "name" "$section" "name" ""
config_get "config" "$section" "config" ""
if [ -n "$name" ] && [ "$config" = "$CONFIG_NAME" ]; then
echo "$server_num.$name" >>"$match_servers"
fi
server_num=$(( $server_num + 1 ))
}
LOG_OUT "Start Getting【$CONFIG_NAME】Proxy-providers Setting..."
echo "" >"$match_provider"
provider_nums=0
config_load "openclash"
config_foreach yml_provider_name_get "proxy-provider"
LOG_OUT "Start Getting【$CONFIG_NAME】Proxies Setting..."
echo "" >"$match_servers"
server_num=0
config_load "openclash"
config_foreach yml_servers_name_get "servers"
#获取代理集信息
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
begin
Value = YAML.load_file('$CONFIG_FILE');
rescue Exception => e
YAML.LOG('Error: Load File Failed,【' + e.message + '】');
YAML.LOG_ERROR('Load File Failed,【' + e.message + '】');
end;
threads = [];
@@ -176,37 +78,16 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
threads_pr << Thread.new {
begin
YAML.LOG('Start Getting【${CONFIG_NAME} - ' + y['type'].to_s + ' - ' + x.to_s + '】Proxy-provider Setting...');
#代理集存在时获取代理集编号
cmd = 'grep -F \'.' + x + '\' ${match_provider} 2>/dev/null |awk -F \".\" \'{print \$1}\'';
provider_nums = %x(#{cmd}).chomp;
if not provider_nums.empty? then
cmd = 'sed -i \"/^' + provider_nums + '\./c\\#match#\" $match_provider 2>/dev/null';
system(cmd);
uci_set='set openclash.@proxy-provider[' + provider_nums + '].';
uci_add='add_list openclash.@proxy-provider[' + provider_nums + '].';
uci_del='uci -q delete openclash.@proxy-provider[' + provider_nums + '].';
if not provider_nums then
uci_commands << uci_set + 'manual=0';
end;
uci_commands << uci_set + 'type=\"' + y['type'].to_s + '\"';
uci_name_tmp_prv[index] = 'uci -q delete openclash.' + uci_name_tmp_prv[index];
else
#代理集不存在时添加新代理集
uci_set='set openclash.' + uci_name_tmp_prv[index] + '.';
uci_add='add_list openclash.' + uci_name_tmp_prv[index] + '.';
uci_del='uci -q delete openclash.' + uci_name_tmp_prv[index] + '.';
if '$new_server_add_group'.to_s.strip.empty? and '$servers_if_update' == '1' and '$servers_update' == 1 then
uci_commands << uci_set + 'enabled=0';
else
uci_commands << uci_set + 'enabled=1';
end;
uci_commands << uci_set + 'manual=0';
uci_commands << uci_set + 'config=\"$CONFIG_NAME\"';
next unless x && y['type'];
uci_commands << uci_set + 'name=\"' + x.to_s + '\"';
uci_commands << uci_set + 'type=\"' + y['type'].to_s + '\"';
end;
#代理集不存在时添加新代理集
uci_set='set openclash.' + uci_name_tmp_prv[index] + '.';
uci_add='add_list openclash.' + uci_name_tmp_prv[index] + '.';
uci_del='uci -q delete openclash.' + uci_name_tmp_prv[index] + '.';
uci_commands << uci_set + 'enabled=1';
uci_commands << uci_set + 'manual=0';
uci_commands << uci_set + 'config=\"$CONFIG_NAME\"';
next unless x && y['type'];
uci_commands << uci_set + 'name=\"' + x.to_s + '\"';
uci_commands << uci_set + 'type=\"' + y['type'].to_s + '\"';
threads_prv << Thread.new{
#path
@@ -269,36 +150,28 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
threads_prv << Thread.new{
#加入策略组
if '$servers_if_update' == '1' and ! '$new_server_add_group'.to_s.strip.empty? and '$servers_update' == '1' and provider_nums.empty? then
#新代理集且设置默认策略组时加入指定策略组
new_provider_groups = '$new_server_add_group'.to_s.split('|||').map(&:strip).reject(&:empty?);
new_provider_groups.each do |x|
uci_commands << uci_add + 'groups=\"^' + x + '$\"'
end
elsif '$servers_if_update' != '1' then
threads_agr = [];
cmd = uci_del + 'groups >/dev/null 2>&1';
system(cmd);
Value['proxy-groups'].each{
|z|
threads_agr << Thread.new {
if z.key?('use') then
z['use'].each{
|v|
if v == x then
uci_commands << uci_add + 'groups=\"^' + z['name'] + '$\"'
break
end
}
threads_agr = [];
cmd = uci_del + 'groups >/dev/null 2>&1';
system(cmd);
Value['proxy-groups'].each{
|z|
threads_agr << Thread.new {
if z.key?('use') then
z['use'].each{
|v|
if v == x then
uci_commands << uci_add + 'groups=\"^' + z['name'] + '$\"'
break
end
};
}
end
};
threads_agr.each(&:join);
end;
};
threads_agr.each(&:join);
};
threads_prv.each(&:join);
rescue Exception => e
YAML.LOG('Error: Resolve Proxy-providers Failed,【${CONFIG_NAME} - ' + x + ': ' + e.message + '】');
YAML.LOG_ERROR('Resolve Proxy-providers Failed,【${CONFIG_NAME} - ' + x + ': ' + e.message + '】');
ensure
queue.pop
end;
@@ -311,36 +184,16 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
threads_pr << Thread.new {
begin
YAML.LOG('Start Getting【${CONFIG_NAME} - ' + x['type'].to_s + ' - ' + x['name'].to_s + '】Proxy Setting...');
#节点存在时获取节点编号
cmd = 'grep -F \'.' + x['name'].to_s + '\' ${match_servers} 2>/dev/null |awk -F \".\" \'{print \$1}\'';
server_num = %x(#{cmd}).chomp;
if not server_num.empty? then
#更新已有节点
cmd = 'sed -i \"/^' + server_num + '\./c\\#match#\" $match_servers 2>/dev/null';
system(cmd);
uci_set='set openclash.@servers[' + server_num + '].';
uci_add='add_list openclash.@servers[' + server_num + '].';
uci_del='uci -q delete openclash.@servers[' + server_num + '].';
if not server_num then
uci_commands << uci_set + 'manual=0';
end;
uci_name_tmp[index] = 'uci -q delete openclash.' + uci_name_tmp[index];
else
#添加新节点
uci_set='set openclash.' + uci_name_tmp[index] + '.';
uci_add='add_list openclash.' + uci_name_tmp[index] + '.';
uci_del='uci -q delete openclash.' + uci_name_tmp[index] + '.';
if '$new_server_add_group'.to_s.strip.empty? and '$servers_if_update' == '1' and '$servers_update' == 1 then
uci_commands << uci_set + 'enabled=0';
else
uci_commands << uci_set + 'enabled=1';
end;
uci_commands << uci_set + 'manual=0';
uci_commands << uci_set + 'config=\"$CONFIG_NAME\"';
next unless x['name'] && x['type'];
if x.key?('name') then
uci_commands << uci_set + 'name=\"' + x['name'].to_s + '\"';
end;
#添加新节点
uci_set='set openclash.' + uci_name_tmp[index] + '.';
uci_add='add_list openclash.' + uci_name_tmp[index] + '.';
uci_del='uci -q delete openclash.' + uci_name_tmp[index] + '.';
uci_commands << uci_set + 'enabled=1';
uci_commands << uci_set + 'manual=0';
uci_commands << uci_set + 'config=\"$CONFIG_NAME\"';
next unless x['name'] && x['type'];
if x.key?('name') then
uci_commands << uci_set + 'name=\"' + x['name'].to_s + '\"';
end;
threads << Thread.new{
@@ -1574,36 +1427,28 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
#加入策略组
threads << Thread.new{
#加入策略组
if '$servers_if_update' == '1' and ! '$new_server_add_group'.to_s.strip.empty? and '$servers_update' == '1' and server_num.empty? then
#新代理且设置默认策略组时加入指定策略组
new_server_groups = '$new_server_add_group'.to_s.split('|||').map(&:strip).reject(&:empty?);
new_server_groups.each do |x|
uci_commands << uci_add + 'groups=\"^' + x + '$\"'
end
elsif '$servers_if_update' != '1' then
threads_gr = [];
cmd = uci_del + 'groups >/dev/null 2>&1';
system(cmd);
Value['proxy-groups'].each{
|z|
threads_gr << Thread.new{
if z.key?('proxies') then
z['proxies'].each{
|v|
if v == x['name'] then
uci_commands << uci_add + 'groups=\"^' + z['name'] + '$\"'
break
end
}
end;
};
threads_gr = [];
cmd = uci_del + 'groups >/dev/null 2>&1';
system(cmd);
Value['proxy-groups'].each{
|z|
threads_gr << Thread.new{
if z.key?('proxies') then
z['proxies'].each{
|v|
if v == x['name'] then
uci_commands << uci_add + 'groups=\"^' + z['name'] + '$\"'
break
end
}
end;
};
threads_gr.each(&:join);
end;
};
threads_gr.each(&:join);
};
threads.each(&:join);
rescue Exception => e
YAML.LOG('Error: Resolve Proxies Failed,【${CONFIG_NAME} - '+ x['type'] + ' - ' + x['name'] + ': ' + e.message + '】');
YAML.LOG_ERROR('Resolve Proxies Failed,【${CONFIG_NAME} - '+ x['type'] + ' - ' + x['name'] + ': ' + e.message + '】');
ensure
queue.pop
end;
@@ -1632,40 +1477,6 @@ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
system('uci -q commit openclash');
" >> $LOG_FILE
#删除订阅中已不存在的代理集
if [ "$servers_if_update" = "1" ]; then
LOG_OUT "Deleting【$CONFIG_NAME】Proxy-providers That no Longer Exists in Subscription"
sed -i '/#match#/d' "$match_provider" 2>/dev/null
cat $match_provider 2>/dev/null|awk -F '.' '{print $1}' |sort -rn |while read line
do
if [ -z "$line" ]; then
continue
fi
if [ "$(uci get openclash.@proxy-provider["$line"].manual)" = "0" ] && [ "$(uci get openclash.@proxy-provider["$line"].config)" = "$CONFIG_NAME" ]; then
uci delete openclash.@proxy-provider["$line"] 2>/dev/null
fi
done
fi
#删除订阅中已不存在的节点
if [ "$servers_if_update" = "1" ]; then
LOG_OUT "Deleting【$CONFIG_NAME】Proxies That no Longer Exists in Subscription"
sed -i '/#match#/d' "$match_servers" 2>/dev/null
cat $match_servers |awk -F '.' '{print $1}' |sort -rn |while read -r line
do
if [ -z "$line" ]; then
continue
fi
if [ "$(uci -q get openclash.@servers["$line"].manual)" = "0" ] && [ "$(uci -q get openclash.@servers["$line"].config)" = "$CONFIG_NAME" ]; then
uci -q delete openclash.@servers["$line"]
fi
done 2>/dev/null
fi
uci -q set openclash.config.servers_if_update=0
uci -q commit openclash
LOG_OUT "Config File【$CONFIG_NAME】Read Successful!"
SLOG_CLEAN
rm -rf /tmp/match_servers.list 2>/dev/null
rm -rf /tmp/match_provider.list 2>/dev/null
del_lock
@@ -16,16 +16,13 @@ del_lock() {
SERVER_FILE="/tmp/yaml_servers.yaml"
PROXY_PROVIDER_FILE="/tmp/yaml_provider.yaml"
servers_if_update=$(uci_get_config "servers_if_update")
config_auto_update=$(uci_get_config "auto_update")
CONFIG_FILE=$(uci_get_config "config_path")
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
UPDATE_CONFIG_FILE=$(uci_get_config "config_update_path")
UPDATE_CONFIG_FILE=$1
UPDATE_CONFIG_NAME=$(echo "$UPDATE_CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
UCI_DEL_LIST="uci -q del_list openclash.config.new_servers_group"
UCI_ADD_LIST="uci -q add_list openclash.config.new_servers_group"
UCI_SET="uci -q set openclash.config."
MIX_PROXY=$(uci_get_config "mix_proxies")
servers_name="/tmp/servers_name.list"
proxy_provider_name="/tmp/provider_name.list"
set_lock
@@ -51,20 +48,6 @@ if [ -z "$CONFIG_NAME" ]; then
CONFIG_NAME="config.yaml"
fi
yml_other_rules_del()
{
local section="$1"
local enabled config
config_get_bool "enabled" "$section" "enabled" "1"
config_get "config" "$section" "config" ""
config_get "rule_name" "$section" "rule_name" ""
if [ "$enabled" = "0" ] || [ "$config" != "$2" ] || [ "$rule_name" != "$3" ]; then
return
else
uci -q set openclash."$section".enabled=0
fi
}
#写入代理集到配置文件
yml_proxy_provider_set()
{
@@ -105,11 +88,7 @@ yml_proxy_provider_set()
return
fi
if [ ! -z "$if_game_proxy" ] && [ "$if_game_proxy" != "$name" ] && [ "$if_game_proxy_type" = "proxy-provider" ]; then
return
fi
if [ "$MIX_PROXY" != "1" ] && [ ! -z "$config" ] && [ "$config" != "$CONFIG_NAME" ] && [ "$config" != "all" ]; then
if [ ! -z "$config" ] && [ "$config" != "$CONFIG_NAME" ] && [ "$config" != "all" ]; then
return
fi
@@ -363,11 +342,7 @@ yml_servers_set()
fi
fi
if [ ! -z "$if_game_proxy" ] && [ "$if_game_proxy" != "$name" ] && [ "$if_game_proxy_type" = "proxy" ]; then
return
fi
if [ "$MIX_PROXY" != "1" ] && [ ! -z "$config" ] && [ "$config" != "$CONFIG_NAME" ] && [ "$config" != "all" ]; then
if [ ! -z "$config" ] && [ "$config" != "$CONFIG_NAME" ] && [ "$config" != "all" ]; then
return
fi
@@ -1637,25 +1612,6 @@ EOF
fi
}
new_servers_group_set()
{
local section="$1"
local enabled name
config_get_bool "enabled" "$section" "enabled" "1"
config_get "name" "$section" "name" ""
if [ "$enabled" = "0" ]; then
return
fi
if [ -z "$name" ] || [ "$(echo $name.yaml)" != "$CONFIG_NAME" ]; then
return
fi
new_servers_group_set=1
}
yml_servers_name_get()
{
local section="$1"
@@ -1677,14 +1633,10 @@ yml_proxy_provider_name_get()
}
#创建配置文件
if_game_proxy="$1"
if_game_proxy_type="$2"
#创建对比文件防止重复
config_load "openclash"
config_foreach yml_servers_name_get "servers"
config_foreach yml_proxy_provider_name_get "proxy-provider"
#判断是否启用保留配置
config_foreach new_servers_group_set "config_subscribe"
#proxy-provider
LOG_OUT "Start Writing【$CONFIG_NAME】Proxy-providers Setting..."
echo "proxy-providers:" >$PROXY_PROVIDER_FILE
@@ -1698,8 +1650,6 @@ fi
rm -rf $proxy_provider_name
#proxy
rule_sources=$(uci_get_config "rule_sources")
create_config=$(uci_get_config "create_config")
LOG_OUT "Start Writing【$CONFIG_NAME】Proxies Setting..."
echo "proxies:" >$SERVER_FILE
config_foreach yml_servers_set "servers"
@@ -1712,551 +1662,23 @@ else
fi
rm -rf $servers_name
#一键创建配置文件
if [ "$rule_sources" = "lhie1" ] && [ "$servers_if_update" != "1" ] && [ -z "$if_game_proxy" ]; then
LOG_OUT "Creating By Using lhie1 Rules..."
echo "proxy-groups:" >>$SERVER_FILE
cat >> "$SERVER_FILE" <<-EOF
- name: Auto - UrlTest
type: url-test
EOF
if [ -f "/tmp/Proxy_Server" ]; then
cat >> "$SERVER_FILE" <<-EOF
proxies:
EOF
fi
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
url: http://cp.cloudflare.com/generate_204
interval: "600"
tolerance: "150"
- name: Proxy
type: select
proxies:
- Auto - UrlTest
- DIRECT
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: Domestic
type: select
proxies:
- DIRECT
- Proxy
- name: Others
type: select
proxies:
- Proxy
- DIRECT
- Domestic
- name: Microsoft
type: select
proxies:
- Proxy
- DIRECT
EOF
cat >> "$SERVER_FILE" <<-EOF
- name: AI Suite
type: select
proxies:
- Proxy
- DIRECT
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: Apple
type: select
proxies:
- Proxy
- DIRECT
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: Apple TV
type: select
proxies:
- Proxy
- DIRECT
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: Google FCM
type: select
proxies:
- Proxy
- DIRECT
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: Scholar
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: Bilibili
type: select
proxies:
- CN Mainland TV
- DIRECT
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: Bahamut
type: select
proxies:
- Global TV
- DIRECT
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: HBO Max
type: select
proxies:
- Global TV
- DIRECT
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: Pornhub
type: select
proxies:
- Global TV
- DIRECT
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: Netflix
type: select
proxies:
- Global TV
- DIRECT
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: Disney Plus
type: select
proxies:
- Global TV
- DIRECT
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: Youtube
type: select
disable-udp: true
proxies:
- Global TV
- DIRECT
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: Discovery Plus
type: select
proxies:
- Global TV
- DIRECT
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: DAZN
type: select
proxies:
- Global TV
- DIRECT
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: Spotify
type: select
proxies:
- Global TV
- DIRECT
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: Steam
type: select
proxies:
- Proxy
- DIRECT
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: TikTok
type: select
proxies:
- Proxy
- DIRECT
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: miHoYo
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: AdBlock
type: select
proxies:
- REJECT
- DIRECT
- Proxy
- name: HTTPDNS
type: select
proxies:
- REJECT
- 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: CN Mainland TV
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:
- Proxy
- DIRECT
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: Global TV
type: select
proxies:
- Proxy
- DIRECT
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: Speedtest
type: select
proxies:
- Proxy
- DIRECT
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: Telegram
type: select
proxies:
- Proxy
- DIRECT
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: Crypto
type: select
proxies:
- Proxy
- DIRECT
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: Discord
type: select
proxies:
- Proxy
- DIRECT
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: PayPal
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
config_load "openclash"
config_foreach yml_other_rules_del "other_rules" "$CONFIG_NAME" "lhie1"
uci_name_tmp=$(uci -q add openclash other_rules)
uci_set="uci -q set openclash.$uci_name_tmp."
${UCI_SET}rule_source="1"
${uci_set}enable="1"
${uci_set}rule_name="lhie1"
${uci_set}config="$CONFIG_NAME"
${uci_set}GlobalTV="Global TV"
${uci_set}AsianTV="Asian TV"
${uci_set}MainlandTV="CN Mainland TV"
${uci_set}Proxy="Proxy"
${uci_set}Youtube="Youtube"
${uci_set}Bilibili="Bilibili"
${uci_set}Bahamut="Bahamut"
${uci_set}HBOMax="HBO Max"
${uci_set}Pornhub="Pornhub"
${uci_set}Apple="Apple"
${uci_set}AppleTV="Apple TV"
${uci_set}GoogleFCM="Google FCM"
${uci_set}Scholar="Scholar"
${uci_set}Microsoft="Microsoft"
${uci_set}AI_Suite="AI Suite"
${uci_set}Netflix="Netflix"
${uci_set}Discovery="Discovery Plus"
${uci_set}DAZN="DAZN"
${uci_set}Disney="Disney Plus"
${uci_set}Spotify="Spotify"
${uci_set}Steam="Steam"
${uci_set}TikTok="TikTok"
${uci_set}miHoYo="miHoYo"
${uci_set}AdBlock="AdBlock"
${uci_set}HTTPDNS="HTTPDNS"
${uci_set}Speedtest="Speedtest"
${uci_set}Telegram="Telegram"
${uci_set}Crypto="Crypto"
${uci_set}Discord="Discord"
${uci_set}PayPal="PayPal"
${uci_set}Domestic="Domestic"
${uci_set}Others="Others"
[ "$config_auto_update" -eq 1 ] && [ "$new_servers_group_set" -eq 1 ] && {
${UCI_SET}servers_update="1"
${UCI_DEL_LIST}="all" >/dev/null 2>&1
${UCI_DEL_LIST}="Auto - UrlTest" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Auto - UrlTest" >/dev/null 2>&1
${UCI_DEL_LIST}="Proxy" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Proxy" >/dev/null 2>&1
${UCI_DEL_LIST}="Youtube" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Youtube" >/dev/null 2>&1
${UCI_DEL_LIST}="Bilibili" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Bilibili" >/dev/null 2>&1
${UCI_DEL_LIST}="Bahamut" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Bahamut" >/dev/null 2>&1
${UCI_DEL_LIST}="HBO Max" >/dev/null 2>&1 && ${UCI_ADD_LIST}="HBO Max" >/dev/null 2>&1
${UCI_DEL_LIST}="Pornhub" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Pornhub" >/dev/null 2>&1
${UCI_DEL_LIST}="Asian TV" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Asian TV" >/dev/null 2>&1
${UCI_DEL_LIST}="CN Mainland TV" >/dev/null 2>&1 && ${UCI_ADD_LIST}="CN Mainland TV" >/dev/null 2>&1
${UCI_DEL_LIST}="Global TV" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Global TV" >/dev/null 2>&1
${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}="AI Suite" >/dev/null 2>&1 && ${UCI_ADD_LIST}="AI Suite" >/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
${UCI_DEL_LIST}="Disney Plus" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Disney Plus" >/dev/null 2>&1
${UCI_DEL_LIST}="Spotify" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Spotify" >/dev/null 2>&1
${UCI_DEL_LIST}="Steam" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Steam" >/dev/null 2>&1
${UCI_DEL_LIST}="TikTok" >/dev/null 2>&1 && ${UCI_ADD_LIST}="TikTok" >/dev/null 2>&1
${UCI_DEL_LIST}="miHoYo" >/dev/null 2>&1 && ${UCI_ADD_LIST}="miHoYo" >/dev/null 2>&1
${UCI_DEL_LIST}="Telegram" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Telegram" >/dev/null 2>&1
${UCI_DEL_LIST}="Crypto" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Crypto" >/dev/null 2>&1
${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}="Others" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Others" >/dev/null 2>&1
}
LOG_OUT "Proxies, Proxy-providers, Groups Edited Successful, Updating Config File【$CONFIG_NAME】..."
config_hash=$(ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "Value = YAML.load_file('$CONFIG_FILE'); puts Value" 2>/dev/null)
if [ "$config_hash" != "false" ] && [ -n "$config_hash" ]; then
ruby_cover "$CONFIG_FILE" "['proxies']" "$SERVER_FILE" "proxies"
ruby_cover "$CONFIG_FILE" "['proxy-providers']" "$PROXY_PROVIDER_FILE" "proxy-providers"
ruby_cover "$CONFIG_FILE" "['proxy-groups']" "/tmp/yaml_groups.yaml" "proxy-groups"
else
cat "$SERVER_FILE" "$PROXY_PROVIDER_FILE" "/tmp/yaml_groups.yaml" > "$CONFIG_FILE" 2>/dev/null
fi
if [ "$create_config" != "0" ] && [ "$servers_if_update" != "1" ] && [ -z "$if_game_proxy" ]; then
echo "rules:" >>$SERVER_FILE
LOG_OUT "Config File【$CONFIG_NAME】Created Successful, Updating Proxies, Proxy-providers, Groups..."
cat "$PROXY_PROVIDER_FILE" > "$CONFIG_FILE" 2>/dev/null
cat "$SERVER_FILE" >> "$CONFIG_FILE" 2>/dev/null
/usr/share/openclash/yml_groups_get.sh >/dev/null 2>&1
elif [ -z "$if_game_proxy" ]; then
LOG_OUT "Proxies, Proxy-providers, Groups Edited Successful, Updating Config File【$CONFIG_NAME】..."
config_hash=$(ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "Value = YAML.load_file('$CONFIG_FILE'); puts Value" 2>/dev/null)
if [ "$config_hash" != "false" ] && [ -n "$config_hash" ]; then
ruby_cover "$CONFIG_FILE" "['proxies']" "$SERVER_FILE" "proxies"
ruby_cover "$CONFIG_FILE" "['proxy-providers']" "$PROXY_PROVIDER_FILE" "proxy-providers"
ruby_cover "$CONFIG_FILE" "['proxy-groups']" "/tmp/yaml_groups.yaml" "proxy-groups"
else
cat "$SERVER_FILE" "$PROXY_PROVIDER_FILE" "/tmp/yaml_groups.yaml" > "$CONFIG_FILE" 2>/dev/null
fi
fi
if [ -z "$if_game_proxy" ]; then
rm -rf $SERVER_FILE 2>/dev/null
rm -rf $PROXY_PROVIDER_FILE 2>/dev/null
rm -rf /tmp/yaml_groups.yaml 2>/dev/null
LOG_OUT "Config File【$CONFIG_NAME】Write Successful!"
SLOG_CLEAN
fi
rm -rf $SERVER_FILE 2>/dev/null
rm -rf $PROXY_PROVIDER_FILE 2>/dev/null
rm -rf /tmp/yaml_groups.yaml 2>/dev/null
rm -rf /tmp/Proxy_Server 2>/dev/null
rm -rf /tmp/Proxy_Provider 2>/dev/null
del_lock
${UCI_SET}enable=1 2>/dev/null
[ "$(uci_get_config "servers_if_update")" == "0" ] && [ -z "$if_game_proxy" ] && /etc/init.d/openclash restart >/dev/null 2>&1
${UCI_SET}servers_if_update=0
uci -q commit openclash
LOG_OUT "Config File【$CONFIG_NAME】Write Successful!"
SLOG_CLEAN
del_lock
File diff suppressed because it is too large. Load diff