Files
op-packages/luci-app-openclash/root/usr/share/openclash/yml_proxys_get.sh
T

1672 lines
62 KiB
Bash
Executable File

#!/bin/bash
. /lib/functions.sh
. /usr/share/openclash/log.sh
. /usr/share/openclash/uci.sh
set_lock() {
exec 875>"/tmp/lock/openclash_proxies_get.lock" 2>/dev/null
flock -x 875 2>/dev/null
}
del_lock() {
flock -u 875 2>/dev/null
rm -rf "/tmp/lock/openclash_proxies_get.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_NAME=$(echo "$UPDATE_CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
LOG_FILE="/tmp/openclash.log"
set_lock
if [ ! -z "$UPDATE_CONFIG_FILE" ]; then
CONFIG_FILE="$UPDATE_CONFIG_FILE"
CONFIG_NAME="$UPDATE_CONFIG_NAME"
fi
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
BACKUP_FILE="/etc/openclash/backup/$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)"
if [ ! -s "$CONFIG_FILE" ] && [ ! -s "$BACKUP_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 + '】');
end;
threads = [];
threads_prv = [];
threads_pr = [];
threads_uci = [];
uci_commands = [];
uci_name_tmp_prv = [];
uci_name_tmp = [];
max_threads = 30
queue = SizedQueue.new(max_threads)
if not Value.key?('proxy-providers') or Value['proxy-providers'].nil? then
Value['proxy-providers'] = {};
end;
if not Value.key?('proxies') or Value['proxies'].nil? then
Value['proxies'] = [];
end;
Value['proxy-providers'].each_with_index do |(x,y), index|
uci_name_tmp_prv << %x{uci -q add openclash proxy-provider 2>&1}.chomp;
queue.push(nil)
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;
threads_prv << Thread.new{
#path
if y.key?('path') then
if y['type'] == 'http' then
uci_commands << uci_set + 'path=\"./proxy_provider/' + x + '.yaml\"'
else
uci_commands << uci_set + 'path=\"' + y['path'].to_s + '\"'
end
end
};
threads_prv << Thread.new{
#gen_url
if y.key?('url') then
uci_commands << uci_set + 'provider_url=\"' + y['url'].to_s + '\"'
end
};
threads_prv << Thread.new{
#gen_interval
if y.key?('interval') then
uci_commands << uci_set + 'provider_interval=\"' + y['interval'].to_s + '\"'
end
};
threads_prv << Thread.new{
#filter
if y.key?('filter') then
uci_commands << uci_set + 'provider_filter=\"' + y['filter'].to_s + '\"'
end
};
threads_prv << Thread.new{
#che_enable
if y.key?('health-check') then
if y['health-check'].key?('enable') then
uci_commands << uci_set + 'health_check=\"' + y['health-check']['enable'].to_s + '\"'
end
end
};
threads_prv << Thread.new{
#che_url
if y.key?('health-check') then
if y['health-check'].key?('url') then
uci_commands << uci_set + 'health_check_url=\"' + y['health-check']['url'].to_s + '\"'
end
end
};
threads_prv << Thread.new{
#che_interval
if y.key?('health-check') then
if y['health-check'].key?('interval') then
uci_commands << uci_set + 'health_check_interval=\"' + y['health-check']['interval'].to_s + '\"'
end
end
};
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
}
end
};
};
threads_agr.each(&:join);
end;
};
threads_prv.each(&:join);
rescue Exception => e
YAML.LOG('Error: Resolve Proxy-providers Failed,【${CONFIG_NAME} - ' + x + ': ' + e.message + '】');
ensure
queue.pop
end;
};
end;
Value['proxies'].each_with_index do |x, index|
uci_name_tmp << %x{uci -q add openclash servers 2>&1}.chomp;
queue.push(nil)
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;
end;
threads << Thread.new{
#type
if x.key?('type') then
uci_commands << uci_set + 'type=\"' + x['type'].to_s + '\"';
end
};
threads << Thread.new{
#server
if x.key?('server') then
uci_commands << uci_set + 'server=\"' + x['server'].to_s + '\"'
end
};
threads << Thread.new{
#port
if x.key?('port') then
uci_commands << uci_set + 'port=\"' + x['port'].to_s + '\"'
end
};
threads << Thread.new{
#udp
if x.key?('udp') then
uci_commands << uci_set + 'udp=\"' + x['udp'].to_s + '\"'
end
};
threads << Thread.new{
#interface-name
if x.key?('interface-name') then
uci_commands << uci_set + 'interface_name=\"' + x['interface-name'].to_s + '\"'
end
};
threads << Thread.new{
#routing-mark
if x.key?('routing-mark') then
uci_commands << uci_set + 'routing_mark=\"' + x['routing-mark'].to_s + '\"'
end;
};
threads << Thread.new{
#ip_version
if x.key?('ip-version') then
uci_commands << uci_set + 'ip_version=\"' + x['ip-version'].to_s + '\"'
end
};
threads << Thread.new{
#TFO
if x.key?('tfo') then
uci_commands << uci_set + 'tfo=\"' + x['tfo'].to_s + '\"'
end
};
threads << Thread.new{
#dialer-proxy
if x.key?('dialer-proxy') then
uci_commands << uci_set + 'dialer_proxy=\"' + x['dialer-proxy'].to_s + '\"'
end
};
if x['type'] == 'ss' then
threads << Thread.new{
#cipher
if x.key?('cipher') then
uci_commands << uci_set + 'cipher=\"' + x['cipher'].to_s + '\"'
end
};
threads << Thread.new{
#udp-over-tcp
if x.key?('udp-over-tcp') then
uci_commands << uci_set + 'udp_over_tcp=\"' + x['udp-over-tcp'].to_s + '\"'
end
};
threads << Thread.new{
#Multiplex
if x.key?('smux') then
if x['smux'].key?('enabled') then
uci_commands << uci_set + 'multiplex=\"' + x['smux']['enabled'].to_s + '\"'
end;
#multiplex_protocol
if x['smux'].key?('protocol') then
uci_commands << uci_set + 'multiplex_protocol=\"' + x['smux']['protocol'].to_s + '\"'
end;
#multiplex_max_connections
if x['smux'].key?('max-connections') then
uci_commands << uci_set + 'multiplex_max_connections=\"' + x['smux']['max-connections'].to_s + '\"'
end;
#multiplex_min_streams
if x['smux'].key?('min-streams') then
uci_commands << uci_set + 'multiplex_min_streams=\"' + x['smux']['min-streams'].to_s + '\"'
end;
#multiplex_max_streams
if x['smux'].key?('max-streams') then
uci_commands << uci_set + 'multiplex_max_streams=\"' + x['smux']['max-streams'].to_s + '\"'
end;
#multiplex_padding
if x['smux'].key?('padding') then
uci_commands << uci_set + 'multiplex_padding=\"' + x['smux']['padding'].to_s + '\"'
end;
#multiplex_statistic
if x['smux'].key?('statistic') then
uci_commands << uci_set + 'multiplex_statistic=\"' + x['smux']['statistic'].to_s + '\"'
end;
#multiplex_only_tcp
if x['smux'].key?('only-tcp') then
uci_commands << uci_set + 'multiplex_only_tcp=\"' + x['smux']['only-tcp'].to_s + '\"'
end;
end;
};
threads << Thread.new{
#plugin-opts
if x.key?('plugin-opts') then
#mode
if x['plugin-opts'].key?('mode') then
uci_commands << uci_set + 'obfs=\"' + x['plugin-opts']['mode'].to_s + '\"'
else
uci_commands << uci_set + 'obfs=none'
end
#host:
if x['plugin-opts'].key?('host') then
uci_commands << uci_set + 'host=\"' + x['plugin-opts']['host'].to_s + '\"'
end
#fingerprint
if x['plugin-opts'].key?('fingerprint') then
uci_commands << uci_set + 'fingerprint=\"' + x['plugin-opts']['fingerprint'].to_s + '\"'
end
if x['plugin'].to_s == 'v2ray-plugin' then
#path
if x['plugin-opts'].key?('path') then
uci_commands << uci_set + 'path=\"' + x['plugin-opts']['path'].to_s + '\"'
end
#mux
if x['plugin-opts'].key?('mux') then
uci_commands << uci_set + 'mux=\"' + x['plugin-opts']['mux'].to_s + '\"'
end
#headers
if x['plugin-opts'].key?('headers') then
if x['plugin-opts']['headers'].key?('custom') then
uci_commands << uci_set + 'custom=\"' + x['plugin-opts']['headers']['custom'].to_s + '\"'
end
end
#tls
if x['plugin-opts'].key?('tls') then
uci_commands << uci_set + 'tls=\"' + x['plugin-opts']['tls'].to_s + '\"'
end
#skip-cert-verify
if x['plugin-opts'].key?('skip-cert-verify') then
uci_commands << uci_set + 'skip_cert_verify=\"' + x['plugin-opts']['skip-cert-verify'].to_s + '\"'
end
end;
if x['plugin'].to_s == 'shadow-tls' then
uci_commands << uci_set + 'obfs=\"' + x['plugin'].to_s + '\"'
#password
if x['plugin-opts'].key?('password') then
uci_commands << uci_set + 'obfs_password=\"' + x['plugin-opts']['password'].to_s + '\"'
end
end;
if x['plugin'].to_s == 'restls' then
uci_commands << uci_set + 'obfs=\"' + x['plugin'].to_s + '\"'
#password
if x['plugin-opts'].key?('password') then
uci_commands << uci_set + 'obfs_password=\"' + x['plugin-opts']['password'].to_s + '\"'
end
#version-hint
if x['plugin-opts'].key?('version-hint') then
uci_commands << uci_set + 'obfs_version_hint=\"' + x['plugin-opts']['version-hint'].to_s + '\"'
end
#restls-script
if x['plugin-opts'].key?('restls-script') then
uci_commands << uci_set + 'obfs_restls_script=\"' + x['plugin-opts']['restls-script'].to_s + '\"'
end
end;
end
};
end;
if x['type'] == 'ssr' then
threads << Thread.new{
#cipher
if x.key?('cipher') then
uci_commands << uci_set + 'cipher_ssr=\"' + x['cipher'].to_s + '\"'
end
};
threads << Thread.new{
#obfs
if x.key?('obfs') then
uci_commands << uci_set + 'obfs_ssr=\"' + x['obfs'].to_s + '\"'
end
};
threads << Thread.new{
#protocol
if x.key?('protocol') then
uci_commands << uci_set + 'protocol=\"' + x['protocol'].to_s + '\"'
end
};
threads << Thread.new{
#obfs-param
if x.key?('obfs-param') then
uci_commands << uci_set + 'obfs_param=\"' + x['obfs-param'].to_s + '\"'
end
};
threads << Thread.new{
#protocol-param
if x.key?('protocol-param') then
uci_commands << uci_set + 'protocol_param=\"' + x['protocol-param'].to_s + '\"'
end
};
end;
if x['type'] == 'vmess' then
threads << Thread.new{
#uuid
if x.key?('uuid') then
uci_commands << uci_set + 'uuid=\"' + x['uuid'].to_s + '\"'
end
};
threads << Thread.new{
#alterId
if x.key?('alterId') then
uci_commands << uci_set + 'alterId=\"' + x['alterId'].to_s + '\"'
end
};
threads << Thread.new{
#cipher
if x.key?('cipher') then
uci_commands << uci_set + 'securitys=\"' + x['cipher'].to_s + '\"'
end
};
threads << Thread.new{
#xudp
if x.key?('xudp') then
uci_commands << uci_set + 'xudp=\"' + x['xudp'].to_s + '\"'
end
};
threads << Thread.new{
#packet_encoding
if x.key?('packet-encoding') then
uci_commands << uci_set + 'packet_encoding=\"' + x['packet-encoding'].to_s + '\"'
end
};
threads << Thread.new{
#GlobalPadding
if x.key?('global-padding') then
uci_commands << uci_set + 'global_padding=\"' + x['global-padding'].to_s + '\"'
end
};
threads << Thread.new{
#authenticated_length
if x.key?('authenticated-length') then
uci_commands << uci_set + 'authenticated_length=\"' + x['authenticated-length'].to_s + '\"'
end
};
threads << Thread.new{
#tls
if x.key?('tls') then
uci_commands << uci_set + 'tls=\"' + x['tls'].to_s + '\"'
end
};
threads << Thread.new{
#skip-cert-verify
if x.key?('skip-cert-verify') then
uci_commands << uci_set + 'skip_cert_verify=\"' + x['skip-cert-verify'].to_s + '\"'
end
};
threads << Thread.new{
#servername
if x.key?('servername') then
uci_commands << uci_set + 'servername=\"' + x['servername'].to_s + '\"'
end
};
threads << Thread.new{
#fingerprint
if x.key?('fingerprint') then
uci_commands << uci_set + 'fingerprint=\"' + x['fingerprint'].to_s + '\"'
end
};
threads << Thread.new{
#client_fingerprint
if x.key?('client-fingerprint') then
uci_commands << uci_set + 'client_fingerprint=\"' + x['client-fingerprint'].to_s + '\"'
end
};
threads << Thread.new{
#network:
if x.key?('network') then
if x['network'].to_s == 'ws'
uci_commands << uci_set + 'obfs_vmess=websocket'
#ws-path:
if x.key?('ws-path') then
uci_commands << uci_set + 'ws_opts_path=\"' + x['ws-path'].to_s + '\"'
end
#Host:
if x.key?('ws-headers') then
cmd = uci_del + 'ws_opts_headers >/dev/null 2>&1'
system(cmd)
x['ws-headers'].keys.each{
|v|
uci_commands << uci_add + 'ws_opts_headers=\"' + v.to_s + ': '+ x['ws-headers'][v].to_s + '\"'
}
end
#ws-opts-path:
if x.key?('ws-opts') then
if x['ws-opts'].key?('path') then
uci_commands << uci_set + 'ws_opts_path=\"' + x['ws-opts']['path'].to_s + '\"'
end
#ws-opts-headers:
if x['ws-opts'].key?('headers') then
cmd = uci_del + 'ws_opts_headers >/dev/null 2>&1'
system(cmd)
x['ws-opts']['headers'].keys.each{
|v|
uci_commands << uci_add + 'ws_opts_headers=\"' + v.to_s + ': '+ x['ws-opts']['headers'][v].to_s + '\"'
}
end
#max-early-data:
if x['ws-opts'].key?('max-early-data') then
uci_commands << uci_set + 'max_early_data=\"' + x['ws-opts']['max-early-data'].to_s + '\"'
end
#early-data-header-name:
if x['ws-opts'].key?('early-data-header-name') then
uci_commands << uci_set + 'early_data_header_name=\"' + x['ws-opts']['early-data-header-name'].to_s + '\"'
end
end
elsif x['network'].to_s == 'http'
uci_commands << uci_set + 'obfs_vmess=http'
if x.key?('http-opts') then
if x['http-opts'].key?('path') then
cmd = uci_del + 'http_path >/dev/null 2>&1'
system(cmd)
x['http-opts']['path'].each{
|x|
uci_commands << uci_add + 'http_path=\"' + x.to_s + '\"'
}
end
if x['http-opts'].key?('headers') then
if x['http-opts']['headers'].key?('Connection') then
if x['http-opts']['headers']['Connection'].include?('keep-alive') then
uci_commands << uci_set + 'keep_alive=true'
else
uci_commands << uci_set + 'keep_alive=false'
end
end
end
end
elsif x['network'].to_s == 'h2'
uci_commands << uci_set + 'obfs_vmess=h2'
if x.key?('h2-opts') then
if x['h2-opts'].key?('host') then
cmd = uci_del + 'h2_host >/dev/null 2>&1'
system(cmd)
x['h2-opts']['host'].each{
|x|
uci_commands << uci_add + 'h2_host=\"' + x.to_s + '\"'
}
end
if x['h2-opts'].key?('path') then
uci_commands << uci_set + 'h2_path=\"' + x['h2-opts']['path'].to_s + '\"'
end
end
elsif x['network'].to_s == 'grpc'
#grpc-service-name
uci_commands << uci_set + 'obfs_vmess=grpc'
if x.key?('grpc-opts') then
if x['grpc-opts'].key?('grpc-service-name') then
uci_commands << uci_set + 'grpc_service_name=\"' + x['grpc-opts']['grpc-service-name'].to_s + '\"'
end
end
else
uci_commands << uci_set + 'obfs_vmess=none'
end
end
};
end;
#Mieru
if x['type'] == 'mieru' then
threads << Thread.new{
#port-range
if x.key?('port-range') then
uci_commands << uci_set + 'port_range=\"' + x['port-range'].to_s + '\"'
end
};
threads << Thread.new{
#username
if x.key?('username') then
uci_commands << uci_set + 'username=\"' + x['username'].to_s + '\"'
end
};
threads << Thread.new{
#transport
if x.key?('transport') then
uci_commands << uci_set + 'transport=\"' + x['transport'].to_s + '\"'
end
};
threads << Thread.new{
#multiplexing
if x.key?('multiplexing') then
uci_commands << uci_set + 'multiplexing=\"' + x['multiplexing'].to_s + '\"'
end
};
end;
#AnyTLS
if x['type'] == 'anytls' then
threads << Thread.new{
if x.key?('password') then
uci_commands << uci_set + 'password=\"' + x['password'].to_s + '\"'
end
};
#idle-session-check-interval
threads << Thread.new{
if x.key?('idle-session-check-interval') then
uci_commands << uci_set + 'idle_session_check_interval=\"' + x['idle-session-check-interval'].to_s + '\"'
end
};
#idle-session-timeout
threads << Thread.new{
if x.key?('idle-session-timeout') then
uci_commands << uci_set + 'idle_session_timeout=\"' + x['idle-session-timeout'].to_s + '\"'
end
};
#min-idle-session
threads << Thread.new{
if x.key?('min-idle-session') then
uci_commands << uci_set + 'min_idle_session=\"' + x['min-idle-session'].to_s + '\"'
end
};
#alpn
threads << Thread.new{
if x.key?('alpn') then
alpn = uci_del + 'alpn >/dev/null 2>&1'
system(alpn)
x['alpn'].each{
|x|
uci_commands << uci_add + 'alpn=\"' + x.to_s + '\"'
}
end
};
#sni
threads << Thread.new{
if x.key?('sni') then
uci_commands << uci_set + 'sni=\"' + x['sni'].to_s + '\"'
end
};
#skip-cert-verify
threads << Thread.new{
if x.key?('skip-cert-verify') then
uci_commands << uci_set + 'skip_cert_verify=\"' + x['skip-cert-verify'].to_s + '\"'
end
};
#client_fingerprint
threads << Thread.new{
if x.key?('client-fingerprint') then
uci_commands << uci_set + 'client_fingerprint=\"' + x['client-fingerprint'].to_s + '\"'
end
};
end;
#Tuic
if x['type'] == 'tuic' then
threads << Thread.new{
#tc_ip
if x.key?('ip') then
uci_commands << uci_set + 'tc_ip=\"' + x['ip'].to_s + '\"'
end
};
threads << Thread.new{
#tc_token
if x.key?('token') then
uci_commands << uci_set + 'tc_token=\"' + x['token'].to_s + '\"'
end
};
threads << Thread.new{
#tc_uuid
if x.key?('uuid') then
uci_commands << uci_set + 'tc_uuid=\"' + x['uuid'].to_s + '\"'
end;
};
threads << Thread.new{
#tc_password
if x.key?('password') then
uci_commands << uci_set + 'tc_password=\"' + x['password'].to_s + '\"'
end
};
threads << Thread.new{
#heartbeat_interval
if x.key?('heartbeat-interval') then
uci_commands << uci_set + 'heartbeat_interval=\"' + x['heartbeat-interval'].to_s + '\"'
end
};
threads << Thread.new{
#tc_alpn
if x.key?('alpn') then
cmd = uci_del + 'tc_alpn >/dev/null 2>&1'
system(cmd)
x['alpn'].each{
|x|
uci_commands << uci_add + 'tc_alpn=\"' + x.to_s + '\"'
}
end;
};
threads << Thread.new{
#disable_sni
if x.key?('disable-sni') then
uci_commands << uci_set + 'disable_sni=\"' + x['disable-sni'].to_s + '\"'
end
};
threads << Thread.new{
#reduce_rtt
if x.key?('reduce-rtt') then
uci_commands << uci_set + 'reduce_rtt=\"' + x['reduce-rtt'].to_s + '\"'
end
};
threads << Thread.new{
#fast_open
if x.key?('fast-open') then
uci_commands << uci_set + 'fast_open=\"' + x['fast-open'].to_s + '\"'
end
};
threads << Thread.new{
#request_timeout
if x.key?('request-timeout') then
uci_commands << uci_set + 'request_timeout=\"' + x['request-timeout'].to_s + '\"'
end
};
threads << Thread.new{
#udp_relay_mode
if x.key?('udp-relay-mode') then
uci_commands << uci_set + 'udp_relay_mode=\"' + x['udp-relay-mode'].to_s + '\"'
end
};
threads << Thread.new{
#congestion_controller
if x.key?('congestion-controller') then
uci_commands << uci_set + 'congestion_controller=\"' + x['congestion-controller'].to_s + '\"'
end
};
threads << Thread.new{
#max_udp_relay_packet_size
if x.key?('max-udp-relay-packet-size') then
uci_commands << uci_set + 'max_udp_relay_packet_size=\"' + x['max-udp-relay-packet-size'].to_s + '\"'
end
};
threads << Thread.new{
#max-open-streams
if x.key?('max-open-streams') then
uci_commands << uci_set + 'max_open_streams=\"' + x['max-open-streams'].to_s + '\"'
end
};
end;
#WireGuard
if x['type'] == 'wireguard' then
threads << Thread.new{
#wg_ip
if x.key?('ip') then
uci_commands << uci_set + 'wg_ip=\"' + x['ip'].to_s + '\"'
end
};
threads << Thread.new{
#wg_ipv6
if x.key?('ipv6') then
uci_commands << uci_set + 'wg_ipv6=\"' + x['ipv6'].to_s + '\"'
end
};
threads << Thread.new{
#private_key
if x.key?('private-key') then
uci_commands << uci_set + 'private_key=\"' + x['private-key'].to_s + '\"'
end
};
threads << Thread.new{
#public_key
if x.key?('public-key') then
uci_commands << uci_set + 'public_key=\"' + x['public-key'].to_s + '\"'
end
};
threads << Thread.new{
#preshared_key
if x.key?('preshared-key') then
uci_commands << uci_set + 'preshared_key=\"' + x['preshared-key'].to_s + '\"'
end
};
threads << Thread.new{
#wg_mtu
if x.key?('mtu') then
uci_commands << uci_set + 'wg_mtu=\"' + x['mtu'].to_s + '\"'
end
};
threads << Thread.new{
#wg_dns
if x.key?('dns') then
cmd = uci_del + 'wg_dns >/dev/null 2>&1'
system(cmd)
x['dns'].each{
|x|
uci_commands << uci_add + 'wg_dns=\"' + x.to_s + '\"'
}
end;
};
end;
if x['type'] == 'hysteria' then
#hysteria
threads << Thread.new{
#hysteria_protocol
if x.key?('protocol') then
uci_commands << uci_set + 'hysteria_protocol=\"' + x['protocol'].to_s + '\"'
end
};
end;
if x['type'] == 'hysteria2' then
#hysteria2
threads << Thread.new{
#hysteria2_protocol
if x.key?('protocol') then
uci_commands << uci_set + 'hysteria2_protocol=\"' + x['protocol'].to_s + '\"'
end
};
end;
if x['type'] == 'hysteria' or x['type'] == 'hysteria2' then
#hysteria hysteria2
threads << Thread.new{
#hysteria_up
if x.key?('up') then
uci_commands << uci_set + 'hysteria_up=\"' + x['up'].to_s + '\"'
end
};
#hysteria hysteria2
threads << Thread.new{
#hysteria_down
if x.key?('down') then
uci_commands << uci_set + 'hysteria_down=\"' + x['down'].to_s + '\"'
end
};
#hysteria hysteria2
threads << Thread.new{
#skip-cert-verify
if x.key?('skip-cert-verify') then
uci_commands << uci_set + 'skip_cert_verify=\"' + x['skip-cert-verify'].to_s + '\"'
end
};
#hysteria hysteria2
threads << Thread.new{
#sni
if x.key?('sni') then
uci_commands << uci_set + 'sni=\"' + x['sni'].to_s + '\"'
end
};
#hysteria hysteria2
threads << Thread.new{
#alpn
if x.key?('alpn') then
cmd = uci_del + 'hysteria_alpn >/dev/null 2>&1'
system(cmd)
if x['alpn'].class.to_s != 'Array' then
uci_commands << uci_add + 'hysteria_alpn=\"' + x['alpn'].to_s + '\"'
else
x['alpn'].each{
|x|
uci_commands << uci_add + 'hysteria_alpn=\"' + x.to_s + '\"'
}
end
end;
};
#hysteria
threads << Thread.new{
#recv_window_conn
if x.key?('recv-window-conn') then
uci_commands << uci_set + 'recv_window_conn=\"' + x['recv-window-conn'].to_s + '\"'
end
};
#hysteria
threads << Thread.new{
#recv_window
if x.key?('recv-window') then
uci_commands << uci_set + 'recv_window=\"' + x['recv-window'].to_s + '\"'
end
};
#hysteria2
threads << Thread.new{
#initial_stream_receive_window
if x.key?('initial-stream-receive-window') then
uci_commands << uci_set + 'initial_stream_receive_window=\"' + x['initial-stream-receive-window'].to_s + '\"'
end
};
#hysteria2
threads << Thread.new{
#max_stream_receive_window
if x.key?('max-stream-receive-window') then
uci_commands << uci_set + 'max_stream_receive_window=\"' + x['max-stream-receive-window'].to_s + '\"'
end
};
#hysteria2
threads << Thread.new{
#initial_connection_receive_window
if x.key?('initial-connection-receive-window') then
uci_commands << uci_set + 'initial_connection_receive_window=\"' + x['initial-connection-receive-window'].to_s + '\"'
end
};
#hysteria2
threads << Thread.new{
#max_connection_receive_window
if x.key?('max-connection-receive-window') then
uci_commands << uci_set + 'max_connection_receive_window=\"' + x['max-connection-receive-window'].to_s + '\"'
end
};
#hysteria hysteria2
threads << Thread.new{
#hysteria_obfs
if x.key?('obfs') then
uci_commands << uci_set + 'hysteria_obfs=\"' + x['obfs'].to_s + '\"'
end
};
#hysteria hysteria2
threads << Thread.new{
#hysteria_obfs_password
if x.key?('obfs-password') then
uci_commands << uci_set + 'hysteria_obfs_password=\"' + x['obfs-password'].to_s + '\"'
end
};
#hysteria
threads << Thread.new{
#hysteria_auth
if x.key?('auth') then
uci_commands << uci_set + 'hysteria_auth=\"' + x['auth'].to_s + '\"'
end
};
#hysteria
threads << Thread.new{
#hysteria_auth_str
if x.key?('auth-str') then
uci_commands << uci_set + 'hysteria_auth_str=\"' + x['auth-str'].to_s + '\"'
end
};
#hysteria hysteria2
threads << Thread.new{
#hysteria_ca
if x.key?('ca') then
uci_commands << uci_set + 'hysteria_ca=\"' + x['ca'].to_s + '\"'
end
};
#hysteria hysteria2
threads << Thread.new{
#hysteria_ca_str
if x.key?('ca-str') then
uci_commands << uci_set + 'hysteria_ca_str=\"' + x['ca-str'].to_s + '\"'
end
};
#hysteria
threads << Thread.new{
#disable_mtu_discovery
if x.key?('disable-mtu-discovery') then
uci_commands << uci_set + 'disable_mtu_discovery=\"' + x['disable-mtu-discovery'].to_s + '\"'
end
};
#hysteria
threads << Thread.new{
#fast_open
if x.key?('fast-open') then
uci_commands << uci_set + 'fast_open=\"' + x['fast-open'].to_s + '\"'
end
};
#hysteria hysteria2
threads << Thread.new{
#fingerprint
if x.key?('fingerprint') then
uci_commands << uci_set + 'fingerprint=\"' + x['fingerprint'].to_s + '\"'
end
};
#hysteria hysteria2
threads << Thread.new{
#ports
if x.key?('ports') then
uci_commands << uci_set + 'ports=\"' + x['ports'].to_s + '\"'
end
};
#hysteria hysteria2
threads << Thread.new{
#hop-interval
if x.key?('hop-interval') then
uci_commands << uci_set + 'hop_interval=\"' + x['hop-interval'].to_s + '\"'
end
};
end;
if x['type'] == 'vless' then
threads << Thread.new{
#uuid
if x.key?('uuid') then
uci_commands << uci_set + 'uuid=\"' + x['uuid'].to_s + '\"'
end
};
threads << Thread.new{
#tls
if x.key?('tls') then
uci_commands << uci_set + 'tls=\"' + x['tls'].to_s + '\"'
end
};
threads << Thread.new{
#skip-cert-verify
if x.key?('skip-cert-verify') then
uci_commands << uci_set + 'skip_cert_verify=\"' + x['skip-cert-verify'].to_s + '\"'
end
};
threads << Thread.new{
#servername
if x.key?('servername') then
uci_commands << uci_set + 'servername=\"' + x['servername'].to_s + '\"'
end
};
threads << Thread.new{
#flow
if x.key?('flow') then
uci_commands << uci_set + 'vless_flow=\"' + x['flow'].to_s + '\"'
end
};
threads << Thread.new{
#network:
if x.key?('network') then
if x['network'].to_s == 'ws'
uci_commands << uci_set + 'obfs_vless=ws'
#ws-opts-path:
if x.key?('ws-opts') then
if x['ws-opts'].key?('path') then
uci_commands << uci_set + 'ws_opts_path=\"' + x['ws-opts']['path'].to_s + '\"'
end
#ws-opts-headers:
if x['ws-opts'].key?('headers') then
cmd = uci_del + 'ws_opts_headers >/dev/null 2>&1'
system(cmd)
x['ws-opts']['headers'].keys.each{
|v|
uci_commands << uci_add + 'ws_opts_headers=\"' + v.to_s + ': '+ x['ws-opts']['headers'][v].to_s + '\"'
}
end
end
elsif x['network'].to_s == 'grpc'
#grpc-service-name
uci_commands << uci_set + 'obfs_vless=grpc'
if x.key?('grpc-opts') then
if x['grpc-opts'].key?('grpc-service-name') then
uci_commands << uci_set + 'grpc_service_name=\"' + x['grpc-opts']['grpc-service-name'].to_s + '\"'
end
end
if x.key?('reality-opts') then
if x['reality-opts'].key?('public-key') then
uci_commands << uci_set + 'reality_public_key=\"' + x['reality-opts']['public-key'].to_s + '\"'
end
if x['reality-opts'].key?('short-id') then
uci_commands << uci_set + 'reality_short_id=\"' + x['reality-opts']['short-id'].to_s + '\"'
end
end
elsif x['network'].to_s == 'tcp'
uci_commands << uci_set + 'obfs_vless=tcp'
if x.key?('reality-opts') then
if x['reality-opts'].key?('public-key') then
uci_commands << uci_set + 'reality_public_key=\"' + x['reality-opts']['public-key'].to_s + '\"'
end
if x['reality-opts'].key?('short-id') then
uci_commands << uci_set + 'reality_short_id=\"' + x['reality-opts']['short-id'].to_s + '\"'
end
end
end
end
};
threads << Thread.new{
#xudp
if x.key?('xudp') then
uci_commands << uci_set + 'xudp=\"' + x['xudp'].to_s + '\"'
end
};
threads << Thread.new{
#packet-addr
if x.key?('packet-addr') then
uci_commands << uci_set + 'packet_addr=\"' + x['packet-addr'].to_s + '\"'
end
};
threads << Thread.new{
#packet_encoding
if x.key?('packet-encoding') then
uci_commands << uci_set + 'packet_encoding=\"' + x['packet-encoding'].to_s + '\"'
end
};
threads << Thread.new{
#fingerprint
if x.key?('fingerprint') then
uci_commands << uci_set + 'fingerprint=\"' + x['fingerprint'].to_s + '\"'
end
};
threads << Thread.new{
#client_fingerprint
if x.key?('client-fingerprint') then
uci_commands << uci_set + 'client_fingerprint=\"' + x['client-fingerprint'].to_s + '\"'
end
};
end;
if x['type'] == 'snell' then
threads << Thread.new{
if x.key?('obfs-opts') then
if x['obfs-opts'].key?('mode') then
uci_commands << uci_set + 'obfs_snell=\"' + x['obfs-opts']['mode'].to_s + '\"'
else
uci_commands << uci_set + 'obfs_snell=none'
end
if x['obfs-opts'].key?('host') then
uci_commands << uci_set + 'host=\"' + x['obfs-opts']['host'].to_s + '\"'
end
end
};
threads << Thread.new{
if x.key?('psk') then
uci_commands << uci_set + 'psk=\"' + x['psk'].to_s + '\"'
end
};
threads << Thread.new{
if x.key?('version') then
uci_commands << uci_set + 'snell_version=\"' + x['version'].to_s + '\"'
end
};
end;
if x['type'] == 'ssh' then
threads << Thread.new{
if x.key?('username') then
uci_commands << uci_set + 'auth_name=\"' + x['username'].to_s + '\"'
end
};
threads << Thread.new{
if x.key?('password') then
uci_commands << uci_set + 'auth_pass=\"' + x['password'].to_s + '\"'
end
};
threads << Thread.new{
if x.key?('private-key') then
uci_commands << uci_set + 'private_key=\"' + x['private-key'].to_s + '\"'
end
};
threads << Thread.new{
if x.key?('private-key-passphrase') then
uci_commands << uci_set + 'private_key_passphrase=\"' + x['private-key-passphrase'].to_s + '\"'
end
};
threads << Thread.new{
#host-key-algorithms
if x.key?('host-key-algorithms') then
host_key_algorithms = uci_del + 'host_key_algorithms >/dev/null 2>&1'
system(host_key_algorithms)
x['host-key-algorithms'].each{
|x|
uci_commands << uci_add + 'host_key_algorithms=\"' + x.to_s + '\"'
}
end
};
threads << Thread.new{
#host-key
if x.key?('host-key') then
host_key = uci_del + 'host_key >/dev/null 2>&1'
system(host_key)
x['host-key'].each{
|x|
uci_commands << uci_add + 'host_key=\"' + x.to_s + '\"'
}
end
};
end;
if x['type'] == 'socks5' or x['type'] == 'http' then
threads << Thread.new{
if x.key?('username') then
uci_commands << uci_set + 'auth_name=\"' + x['username'].to_s + '\"'
end
};
threads << Thread.new{
if x.key?('password') then
uci_commands << uci_set + 'auth_pass=\"' + x['password'].to_s + '\"'
end
};
threads << Thread.new{
#tls
if x.key?('tls') then
uci_commands << uci_set + 'tls=\"' + x['tls'].to_s + '\"'
end
};
threads << Thread.new{
#skip-cert-verify
if x.key?('skip-cert-verify') then
uci_commands << uci_set + 'skip_cert_verify=\"' + x['skip-cert-verify'].to_s + '\"'
end
};
threads << Thread.new{
#http-headers:
if x.key?('headers') then
cmd = uci_del + 'http_headers >/dev/null 2>&1'
system(cmd)
x['headers'].keys.each{
|v|
uci_commands << uci_add + 'http_headers=\"' + v.to_s + ': '+ x['headers'][v].to_s + '\"'
}
end
};
threads << Thread.new{
#fingerprint
if x.key?('fingerprint') then
uci_commands << uci_set + 'fingerprint=\"' + x['fingerprint'].to_s + '\"'
end
};
else
threads << Thread.new{
if x.key?('password') then
uci_commands << uci_set + 'password=\"' + x['password'].to_s + '\"'
end
};
end;
if x['type'] == 'http' or x['type'] == 'trojan' then
threads << Thread.new{
if x.key?('sni') then
uci_commands << uci_set + 'sni=\"' + x['sni'].to_s + '\"'
end
};
end;
if x['type'] == 'trojan' then
threads << Thread.new{
#alpn
if x.key?('alpn') then
alpn = uci_del + 'alpn >/dev/null 2>&1'
system(alpn)
x['alpn'].each{
|x|
uci_commands << uci_add + 'alpn=\"' + x.to_s + '\"'
}
end
};
threads << Thread.new{
#grpc-service-name
if x.key?('grpc-opts') then
uci_commands << uci_set + 'obfs_trojan=grpc'
if x['grpc-opts'].key?('grpc-service-name') then
uci_commands << uci_set + 'grpc_service_name=\"' + x['grpc-opts']['grpc-service-name'].to_s + '\"'
end
end
};
threads << Thread.new{
if x.key?('ws-opts') then
uci_commands << uci_set + 'obfs_trojan=ws'
#trojan_ws_path
if x['ws-opts'].key?('path') then
uci_commands << uci_set + 'trojan_ws_path=\"' + x['ws-opts']['path'].to_s + '\"'
end
#trojan_ws_headers
if x['ws-opts'].key?('headers') then
cmd = uci_del + 'trojan_ws_headers >/dev/null 2>&1'
system(cmd)
x['ws-opts']['headers'].keys.each{
|v|
uci_commands << uci_add + 'trojan_ws_headers=\"' + v.to_s + ': '+ x['ws-opts']['headers'][v].to_s + '\"'
}
end
end
};
threads << Thread.new{
#skip-cert-verify
if x.key?('skip-cert-verify') then
uci_commands << uci_set + 'skip_cert_verify=\"' + x['skip-cert-verify'].to_s + '\"'
end
};
threads << Thread.new{
#fingerprint
if x.key?('fingerprint') then
uci_commands << uci_set + 'fingerprint=\"' + x['fingerprint'].to_s + '\"'
end
};
threads << Thread.new{
#client_fingerprint
if x.key?('client-fingerprint') then
uci_commands << uci_set + 'client_fingerprint=\"' + x['client-fingerprint'].to_s + '\"'
end
};
end;
if x['type'] == 'sudoku' then
threads << Thread.new{
#key
if x.key?('key') then
uci_commands << uci_set + 'sudoku_key=\"' + x['key'].to_s + '\"'
end
};
threads << Thread.new{
#aead-method
if x.key?('aead-method') then
uci_commands << uci_set + 'aead_method=\"' + x['aead-method'].to_s + '\"'
end
};
threads << Thread.new{
#padding-min
if x.key?('padding-min') then
uci_commands << uci_set + 'padding_min=\"' + x['padding-min'].to_s + '\"'
end
};
threads << Thread.new{
#padding-max
if x.key?('padding-max') then
uci_commands << uci_set + 'padding_max=\"' + x['padding-max'].to_s + '\"'
end
};
threads << Thread.new{
#table-type
if x.key?('table-type') then
uci_commands << uci_set + 'table_type=\"' + x['table-type'].to_s + '\"'
end
};
threads << Thread.new{
#http-mask
if x.key?('http-mask') then
uci_commands << uci_set + 'http_mask=\"' + x['http-mask'].to_s + '\"'
end
};
end;
#加入策略组
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.each(&:join);
end;
};
threads.each(&:join);
rescue Exception => e
YAML.LOG('Error: Resolve Proxies Failed,【${CONFIG_NAME} - '+ x['type'] + ' - ' + x['name'] + ': ' + e.message + '】');
ensure
queue.pop
end;
};
end;
threads_pr.each(&:join);
batch_size = 30;
(0...uci_commands.length).step(batch_size) do |i|
threads_uci << Thread.new{
IO.popen('uci -q batch', 'w') do |pipe|
uci_commands[i, batch_size].each { |cmd| pipe.puts(cmd) }
end
};
end;
threads_uci.each(&:join);
uci_name_tmp.each do |x|
if x =~ /uci -q delete/ then
system(x);
end;
end;
uci_name_tmp_prv.each do |x|
if x =~ /uci -q delete/ then
system(x);
end;
end;
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