修复
This commit is contained in:
@@ -64,7 +64,10 @@
|
||||
"Bash(check_rule_type_conflict:*)",
|
||||
"Bash(apply_outbound_rule)",
|
||||
"Bash(check_existing_outbound_type:*)",
|
||||
"SlashCommand(/sc:analyze:*)"
|
||||
"SlashCommand(/sc:analyze:*)",
|
||||
"Bash(test_dns_resolution:*)",
|
||||
"Bash(echo $?)",
|
||||
"Bash(git checkout:*)"
|
||||
],
|
||||
"deny": []
|
||||
}
|
||||
|
||||
+2
-2
@@ -109,7 +109,7 @@ check_script_integrity() {
|
||||
|
||||
# 检查必需的脚本文件
|
||||
local required_scripts=(
|
||||
"install.sh"
|
||||
# "install.sh" (在根目录)
|
||||
"config.sh"
|
||||
"service.sh"
|
||||
"domain-test.sh"
|
||||
@@ -262,7 +262,7 @@ wait_for_user() {
|
||||
install_hysteria() {
|
||||
log_info "准备安装 Hysteria2..."
|
||||
|
||||
if safe_source_script "$SCRIPTS_DIR/install.sh" "安装脚本"; then
|
||||
if safe_source_script "$SCRIPT_DIR/install.sh" "安装脚本"; then
|
||||
install_hysteria2
|
||||
fi
|
||||
wait_for_user
|
||||
|
||||
+108
-30
@@ -119,42 +119,89 @@ detect_network_quality() {
|
||||
fi
|
||||
}
|
||||
|
||||
# 测试单个域名延迟(优化版本)
|
||||
# DNS解析验证函数
|
||||
test_dns_resolution() {
|
||||
local domain=$1
|
||||
local timeout_val=${2:-3}
|
||||
|
||||
# 使用dig验证DNS解析(优先)
|
||||
if command -v dig >/dev/null 2>&1; then
|
||||
if timeout "$timeout_val" dig +short "$domain" A >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# 使用nslookup作为备用
|
||||
if command -v nslookup >/dev/null 2>&1; then
|
||||
if timeout "$timeout_val" nslookup "$domain" >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# 使用host作为最后备用
|
||||
if command -v host >/dev/null 2>&1; then
|
||||
if timeout "$timeout_val" host "$domain" >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# 测试单个域名延迟(优化版本 + DNS验证)
|
||||
test_domain_latency() {
|
||||
local domain=$1
|
||||
local timeout_val=${2:-3}
|
||||
local attempts=${3:-2} # 默认尝试2次
|
||||
local results=()
|
||||
|
||||
|
||||
# 检查缓存
|
||||
local cache_file=$(get_cache_file "$domain")
|
||||
if is_cache_valid "$cache_file"; then
|
||||
read_from_cache "$cache_file"
|
||||
return 0
|
||||
local cached_result=$(read_from_cache "$cache_file")
|
||||
# 验证缓存结果是否包含DNS验证状态
|
||||
if [[ "$cached_result" =~ dns_ok|dns_fail ]]; then
|
||||
echo "$cached_result"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# 多次测试取最佳结果
|
||||
|
||||
# 首先验证DNS解析
|
||||
local dns_status="dns_fail"
|
||||
if test_dns_resolution "$domain" "$timeout_val"; then
|
||||
dns_status="dns_ok"
|
||||
else
|
||||
# DNS解析失败,直接返回失败状态
|
||||
local result="9999 $domain $dns_status"
|
||||
write_to_cache "$cache_file" "$result"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 多次测试取最佳结果(只有DNS解析成功才测试连接)
|
||||
for ((i=1; i<=attempts; i++)); do
|
||||
local start_time=$(date +%s%3N)
|
||||
|
||||
|
||||
if timeout "$timeout_val" openssl s_client -connect "$domain:443" -servername "$domain" </dev/null >/dev/null 2>&1; then
|
||||
local end_time=$(date +%s%3N)
|
||||
local latency=$((end_time - start_time))
|
||||
results+=($latency)
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
# 如果有成功的测试结果,返回最小值
|
||||
if [[ ${#results[@]} -gt 0 ]]; then
|
||||
local min_latency=$(printf '%s\n' "${results[@]}" | sort -n | head -1)
|
||||
local result="$min_latency $domain"
|
||||
|
||||
local result="$min_latency $domain $dns_status"
|
||||
|
||||
# 写入缓存
|
||||
write_to_cache "$cache_file" "$result"
|
||||
echo "$result"
|
||||
return 0
|
||||
fi
|
||||
|
||||
|
||||
# SSL连接失败但DNS解析成功
|
||||
local result="9999 $domain $dns_status"
|
||||
write_to_cache "$cache_file" "$result"
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -187,14 +234,15 @@ test_all_domains_concurrent_silent() {
|
||||
# 等待所有任务完成
|
||||
wait
|
||||
|
||||
# 返回排序结果
|
||||
# 返回排序结果(过滤DNS失败的域名)
|
||||
if [[ -s "$results_file" ]]; then
|
||||
sort -n "$results_file"
|
||||
# 只返回DNS解析成功且延迟不是9999的结果
|
||||
awk '$1 != 9999 && $3 == "dns_ok" {print $1 " " $2 " " $3}' "$results_file" | sort -n
|
||||
local exit_code=0
|
||||
else
|
||||
local exit_code=1
|
||||
fi
|
||||
|
||||
|
||||
rm -f "$results_file"
|
||||
return $exit_code
|
||||
}
|
||||
@@ -253,14 +301,15 @@ test_all_domains_concurrent() {
|
||||
echo -e "${GREEN}测试完成!${NC}" >&2
|
||||
echo "" >&2
|
||||
|
||||
# 返回排序结果
|
||||
# 返回排序结果(过滤DNS失败的域名)
|
||||
if [[ -s "$results_file" ]]; then
|
||||
sort -n "$results_file"
|
||||
# 只返回DNS解析成功且延迟不是9999的结果
|
||||
awk '$1 != 9999 && $3 == "dns_ok" {print $1 " " $2 " " $3}' "$results_file" | sort -n
|
||||
local exit_code=0
|
||||
else
|
||||
local exit_code=1
|
||||
fi
|
||||
|
||||
|
||||
# 清理临时文件
|
||||
rm -f "$results_file" "$progress_file"
|
||||
return $exit_code
|
||||
@@ -281,11 +330,11 @@ show_test_results() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
printf "%-5s %-30s %-8s %s\n" "排名" "域名" "延迟(ms)" "评级"
|
||||
echo "------------------------------------------------"
|
||||
|
||||
printf "%-5s %-30s %-8s %-8s %s\n" "排名" "域名" "延迟(ms)" "DNS状态" "评级"
|
||||
echo "---------------------------------------------------------"
|
||||
|
||||
local rank=1
|
||||
echo "$results" | head -n 10 | while read -r latency domain; do
|
||||
echo "$results" | head -n 10 | while read -r latency domain dns_status; do
|
||||
# 延迟评级
|
||||
local rating
|
||||
if [[ $latency -lt 50 ]]; then
|
||||
@@ -300,7 +349,15 @@ show_test_results() {
|
||||
rating="${RED}较差${NC}"
|
||||
fi
|
||||
|
||||
printf "%-5d %-30s %-8d %b\n" "$rank" "$domain" "$latency" "$rating"
|
||||
# DNS状态显示
|
||||
local dns_display
|
||||
if [[ "$dns_status" == "dns_ok" ]]; then
|
||||
dns_display="${GREEN}正常${NC}"
|
||||
else
|
||||
dns_display="${RED}失败${NC}"
|
||||
fi
|
||||
|
||||
printf "%-5d %-30s %-8d %-8s %b\n" "$rank" "$domain" "$latency" "$dns_display" "$rating"
|
||||
rank=$((rank + 1))
|
||||
done
|
||||
}
|
||||
@@ -310,7 +367,13 @@ get_best_domain() {
|
||||
local best_result=$(test_all_domains_concurrent_silent | head -n 1)
|
||||
if [[ -n "$best_result" ]]; then
|
||||
local domain=$(echo "$best_result" | awk '{print $2}')
|
||||
echo "https://$domain/"
|
||||
local dns_status=$(echo "$best_result" | awk '{print $3}')
|
||||
# 确保DNS解析成功
|
||||
if [[ "$dns_status" == "dns_ok" ]]; then
|
||||
echo "https://$domain/"
|
||||
else
|
||||
echo "https://news.ycombinator.com/"
|
||||
fi
|
||||
else
|
||||
echo "https://news.ycombinator.com/"
|
||||
fi
|
||||
@@ -320,7 +383,14 @@ get_best_domain() {
|
||||
get_best_domain_name() {
|
||||
local best_result=$(test_all_domains_concurrent_silent | head -n 1)
|
||||
if [[ -n "$best_result" ]]; then
|
||||
echo "$best_result" | awk '{print $2}'
|
||||
local domain=$(echo "$best_result" | awk '{print $2}')
|
||||
local dns_status=$(echo "$best_result" | awk '{print $3}')
|
||||
# 确保DNS解析成功
|
||||
if [[ "$dns_status" == "dns_ok" ]]; then
|
||||
echo "$domain"
|
||||
else
|
||||
echo "cdn.jsdelivr.net"
|
||||
fi
|
||||
else
|
||||
echo "cdn.jsdelivr.net"
|
||||
fi
|
||||
@@ -400,8 +470,9 @@ interactive_domain_selection() {
|
||||
if [[ -n "$line" ]]; then
|
||||
local latency=$(echo "$line" | awk '{print $1}')
|
||||
local domain=$(echo "$line" | awk '{print $2}')
|
||||
local dns_status=$(echo "$line" | awk '{print $3}')
|
||||
|
||||
if [[ "$latency" =~ ^[0-9]+$ ]] && [[ -n "$domain" ]] && [[ ! "$domain" =~ [[:space:]] ]]; then
|
||||
if [[ "$latency" =~ ^[0-9]+$ ]] && [[ -n "$domain" ]] && [[ ! "$domain" =~ [[:space:]] ]] && [[ "$dns_status" == "dns_ok" ]]; then
|
||||
# 延迟评级
|
||||
local rating
|
||||
if [[ $latency -lt 100 ]]; then
|
||||
@@ -411,7 +482,7 @@ interactive_domain_selection() {
|
||||
else
|
||||
rating="${RED}一般${NC}"
|
||||
fi
|
||||
|
||||
|
||||
printf "%-5d %-30s %-8d %b\n" "$index" "$domain" "$latency" "$rating"
|
||||
domains_array+=("$domain")
|
||||
index=$((index + 1))
|
||||
@@ -544,8 +615,8 @@ test_custom_domains() {
|
||||
echo ""
|
||||
echo -e "${BLUE}开始并发测试 ${#custom_domains[@]} 个自定义域名...${NC}"
|
||||
echo ""
|
||||
printf "%-30s %-10s %s\n" "域名" "延迟(ms)" "状态"
|
||||
echo "------------------------------------------------"
|
||||
printf "%-30s %-10s %-8s %s\n" "域名" "延迟(ms)" "DNS状态" "状态"
|
||||
echo "-------------------------------------------------------"
|
||||
|
||||
local results_file=$(mktemp)
|
||||
local network_quality=$(detect_network_quality)
|
||||
@@ -560,10 +631,17 @@ test_custom_domains() {
|
||||
(
|
||||
if result=$(test_domain_latency "$domain" "$timeout_val" 1); then
|
||||
local latency=$(echo "$result" | awk '{print $1}')
|
||||
printf "%-30s %-10d %s\n" "$domain" "$latency" "${GREEN}成功${NC}"
|
||||
local dns_status=$(echo "$result" | awk '{print $3}')
|
||||
local dns_display
|
||||
if [[ "$dns_status" == "dns_ok" ]]; then
|
||||
dns_display="${GREEN}正常${NC}"
|
||||
else
|
||||
dns_display="${RED}失败${NC}"
|
||||
fi
|
||||
printf "%-30s %-10d %-8s %s\n" "$domain" "$latency" "$dns_display" "${GREEN}成功${NC}"
|
||||
echo "$result" >> "$results_file"
|
||||
else
|
||||
printf "%-30s %-10s %s\n" "$domain" "-" "${RED}失败${NC}"
|
||||
printf "%-30s %-10s %-8s %s\n" "$domain" "-" "${RED}失败${NC}" "${RED}失败${NC}"
|
||||
fi
|
||||
) &
|
||||
done
|
||||
|
||||
+274
-75
@@ -2820,54 +2820,200 @@ update_rule_config_value() {
|
||||
fi
|
||||
}
|
||||
|
||||
# 5. 删除出站规则
|
||||
# 获取配置文件中的所有出站规则名称
|
||||
get_config_outbound_rules() {
|
||||
if [[ ! -f "$HYSTERIA_CONFIG" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 提取配置文件中所有的 outbound 规则名称
|
||||
awk '
|
||||
/^[[:space:]]*outbound:[[:space:]]*$/ { in_outbound = 1; next }
|
||||
in_outbound && /^[[:space:]]*[a-zA-Z]+:[[:space:]]*$/ && !/^[[:space:]]*(outbound|transport|auth|masquerade|bandwidth):/ { in_outbound = 0 }
|
||||
in_outbound && /^[[:space:]]*-[[:space:]]*name:[[:space:]]*(.+)$/ {
|
||||
match($0, /name:[[:space:]]*([^[:space:]]+)/, arr)
|
||||
if (arr[1]) print arr[1]
|
||||
}
|
||||
' "$HYSTERIA_CONFIG" 2>/dev/null
|
||||
}
|
||||
|
||||
# 从配置文件中删除指定的出站规则
|
||||
remove_rule_from_config() {
|
||||
local rule_name="$1"
|
||||
|
||||
if [[ ! -f "$HYSTERIA_CONFIG" ]]; then
|
||||
log_error "配置文件不存在"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local temp_config="/tmp/hysteria_delete_config_$$_$(date +%s).yaml"
|
||||
local in_target_rule=false
|
||||
local rule_found=false
|
||||
|
||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||
if [[ "$line" =~ ^[[:space:]]*-[[:space:]]*name:[[:space:]]*${rule_name}[[:space:]]*$ ]]; then
|
||||
in_target_rule=true
|
||||
rule_found=true
|
||||
continue
|
||||
elif [[ "$in_target_rule" == true ]]; then
|
||||
# 检查是否到达下一个规则或段落
|
||||
if [[ "$line" =~ ^[[:space:]]*-[[:space:]]*name: ]] || [[ "$line" =~ ^[[:space:]]*[a-zA-Z]+:[[:space:]]*$ ]] && [[ ! "$line" =~ ^[[:space:]]*(type|direct|socks5|http|addr|url|mode|username|password|insecure): ]]; then
|
||||
in_target_rule=false
|
||||
echo "$line" >> "$temp_config"
|
||||
fi
|
||||
# 在目标规则中的行都跳过
|
||||
else
|
||||
echo "$line" >> "$temp_config"
|
||||
fi
|
||||
done < "$HYSTERIA_CONFIG"
|
||||
|
||||
if [[ "$rule_found" == true ]]; then
|
||||
if safe_move_config "$temp_config" "$HYSTERIA_CONFIG"; then
|
||||
log_success "已从配置文件中删除规则 '$rule_name'"
|
||||
return 0
|
||||
else
|
||||
log_error "配置文件更新失败"
|
||||
rm -f "$temp_config"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log_warn "在配置文件中未找到规则 '$rule_name'"
|
||||
rm -f "$temp_config"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 5. 删除出站规则 (增强版)
|
||||
delete_outbound_rule_new() {
|
||||
init_rules_library
|
||||
|
||||
echo -e "${BLUE}=== 删除出站规则 ===${NC}"
|
||||
echo ""
|
||||
|
||||
# 列出规则库中的规则 - 使用可靠的grep方法
|
||||
local rules=()
|
||||
local rule_count=0
|
||||
|
||||
# 收集规则库中的规则
|
||||
local library_rules=()
|
||||
while IFS= read -r rule_name; do
|
||||
if [[ -n "$rule_name" ]]; then
|
||||
rules+=("$rule_name")
|
||||
((rule_count++))
|
||||
|
||||
# 检查是否已应用 - 只根据配置文件实际状态
|
||||
local status="❌ 未应用"
|
||||
if [[ -f "$HYSTERIA_CONFIG" ]] && grep -q "name:[[:space:]]*[\"']*${rule_name}[\"']*[[:space:]]*$" "$HYSTERIA_CONFIG" 2>/dev/null; then
|
||||
status="✅ 已应用"
|
||||
fi
|
||||
echo "$rule_count. $rule_name $status"
|
||||
library_rules+=("$rule_name")
|
||||
fi
|
||||
done < <(grep -o "^[[:space:]]\{2\}[a-zA-Z_][a-zA-Z0-9_]*:" "$RULES_LIBRARY" | sed 's/^[[:space:]]\{2\}\([^:]*\):.*/\1/')
|
||||
|
||||
if [[ ${#rules[@]} -eq 0 ]]; then
|
||||
echo -e "${YELLOW}没有可删除的规则${NC}"
|
||||
# 收集配置文件中的规则
|
||||
local config_rules=()
|
||||
while IFS= read -r rule_name; do
|
||||
if [[ -n "$rule_name" ]]; then
|
||||
config_rules+=("$rule_name")
|
||||
fi
|
||||
done < <(get_config_outbound_rules)
|
||||
|
||||
# 合并去重规则列表
|
||||
local all_rules=()
|
||||
local rule_sources=() # 记录规则来源: library/config/both
|
||||
local rule_count=0
|
||||
|
||||
# 添加规则库中的规则
|
||||
for rule in "${library_rules[@]}"; do
|
||||
all_rules+=("$rule")
|
||||
rule_sources+=("library")
|
||||
((rule_count++))
|
||||
done
|
||||
|
||||
# 添加配置文件中独有的规则
|
||||
for rule in "${config_rules[@]}"; do
|
||||
local found_in_library=false
|
||||
for lib_rule in "${library_rules[@]}"; do
|
||||
if [[ "$rule" == "$lib_rule" ]]; then
|
||||
found_in_library=true
|
||||
# 更新来源为both
|
||||
for i in "${!all_rules[@]}"; do
|
||||
if [[ "${all_rules[i]}" == "$rule" ]]; then
|
||||
rule_sources[i]="both"
|
||||
break
|
||||
fi
|
||||
done
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$found_in_library" == false ]]; then
|
||||
all_rules+=("$rule")
|
||||
rule_sources+=("config")
|
||||
((rule_count++))
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#all_rules[@]} -eq 0 ]]; then
|
||||
echo -e "${YELLOW}没有找到任何规则${NC}"
|
||||
wait_for_user
|
||||
return
|
||||
fi
|
||||
|
||||
echo -e "${CYAN}找到以下规则:${NC}"
|
||||
echo ""
|
||||
read -p "请选择要删除的规则 [1-$rule_count]: " choice
|
||||
printf "%-5s %-25s %-12s %s\n" "编号" "规则名称" "位置" "状态"
|
||||
echo "---------------------------------------------------"
|
||||
|
||||
for i in "${!all_rules[@]}"; do
|
||||
local rule_name="${all_rules[i]}"
|
||||
local source="${rule_sources[i]}"
|
||||
local status=""
|
||||
|
||||
# 确定位置显示
|
||||
local location_display
|
||||
case "$source" in
|
||||
"library") location_display="${GREEN}规则库${NC}" ;;
|
||||
"config") location_display="${YELLOW}配置文件${NC}" ;;
|
||||
"both") location_display="${BLUE}规则库+配置${NC}" ;;
|
||||
esac
|
||||
|
||||
# 检查应用状态
|
||||
if [[ -f "$HYSTERIA_CONFIG" ]] && grep -q "name:[[:space:]]*[\"']*${rule_name}[\"']*[[:space:]]*$" "$HYSTERIA_CONFIG" 2>/dev/null; then
|
||||
status="✅ 已应用"
|
||||
else
|
||||
status="❌ 未应用"
|
||||
fi
|
||||
|
||||
printf "%-5d %-25s %-12s %s\n" "$((i+1))" "$rule_name" "$location_display" "$status"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo -e "${YELLOW}说明:${NC}"
|
||||
echo "• 规则库: 规则模板,可重复应用"
|
||||
echo "• 配置文件: 当前活动的规则"
|
||||
echo "• 规则库+配置: 存在于两个位置"
|
||||
echo ""
|
||||
|
||||
read -p "请选择要删除的规则编号 [1-$rule_count]: " choice
|
||||
|
||||
if [[ ! "$choice" =~ ^[0-9]+$ ]] || [[ "$choice" -lt 1 ]] || [[ "$choice" -gt $rule_count ]]; then
|
||||
log_error "无效选择"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local selected_rule="${rules[$((choice-1))]}"
|
||||
local selected_rule="${all_rules[$((choice-1))]}"
|
||||
local selected_source="${rule_sources[$((choice-1))]}"
|
||||
|
||||
echo ""
|
||||
echo -e "${RED}⚠️ 警告: 即将删除规则 '$selected_rule'${NC}"
|
||||
|
||||
# 检查是否已应用
|
||||
if grep -q "- $selected_rule" "$RULES_STATE" 2>/dev/null; then
|
||||
echo -e "${YELLOW}此规则当前已应用,删除将同时从配置文件中移除${NC}"
|
||||
fi
|
||||
# 根据规则位置给出不同的提示
|
||||
case "$selected_source" in
|
||||
"library")
|
||||
echo -e "${YELLOW}此规则仅存在于规则库中${NC}"
|
||||
;;
|
||||
"config")
|
||||
echo -e "${YELLOW}此规则仅存在于配置文件中,删除后将立即生效${NC}"
|
||||
;;
|
||||
"both")
|
||||
echo -e "${YELLOW}此规则同时存在于规则库和配置文件中${NC}"
|
||||
echo "选择删除范围:"
|
||||
echo "1. 仅从规则库中删除"
|
||||
echo "2. 仅从配置文件中删除"
|
||||
echo "3. 同时从两个位置删除"
|
||||
echo ""
|
||||
read -p "请选择 [1-3]: " delete_scope
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
read -p "确认删除? [y/N]: " confirm
|
||||
@@ -2877,57 +3023,95 @@ delete_outbound_rule_new() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 如果已应用,先从配置中移除
|
||||
if grep -q "- $selected_rule" "$RULES_STATE" 2>/dev/null; then
|
||||
echo "正在从配置文件中移除..."
|
||||
local delete_success=false
|
||||
|
||||
# 从配置文件中删除
|
||||
if [[ -f "$HYSTERIA_CONFIG" ]]; then
|
||||
local temp_config="/tmp/hysteria_delete_$$_$(date +%s).yaml"
|
||||
local in_target_rule=false
|
||||
|
||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||
if [[ "$line" =~ ^[[:space:]]*-[[:space:]]*name:[[:space:]]*${selected_rule}[[:space:]]*$ ]]; then
|
||||
in_target_rule=true
|
||||
continue
|
||||
elif [[ "$in_target_rule" == true ]]; then
|
||||
if [[ "$line" =~ ^[[:space:]]*-[[:space:]]*name: ]] || [[ "$line" =~ ^[[:space:]]*[a-zA-Z]+:[[:space:]]*$ ]] && [[ ! "$line" =~ ^[[:space:]]*(type|direct|socks5|http|addr|url|mode|username|password|insecure): ]]; then
|
||||
in_target_rule=false
|
||||
echo "$line" >> "$temp_config"
|
||||
fi
|
||||
# 在规则中的行都跳过
|
||||
else
|
||||
echo "$line" >> "$temp_config"
|
||||
fi
|
||||
done < "$HYSTERIA_CONFIG"
|
||||
|
||||
safe_move_config "$temp_config" "$HYSTERIA_CONFIG"
|
||||
fi
|
||||
|
||||
# 从状态文件中移除
|
||||
local temp_state="${RULES_STATE}.tmp"
|
||||
if awk -v rule="$selected_rule" '
|
||||
$0 == " - " rule { next }
|
||||
{ print }
|
||||
' "$RULES_STATE" > "$temp_state" 2>/dev/null; then
|
||||
if [[ -s "$temp_state" ]]; then
|
||||
mv "$temp_state" "$RULES_STATE" 2>/dev/null || rm -f "$temp_state"
|
||||
else
|
||||
rm -f "$temp_state"
|
||||
# 执行删除操作
|
||||
case "$selected_source" in
|
||||
"library")
|
||||
if delete_rule_from_library "$selected_rule"; then
|
||||
delete_success=true
|
||||
fi
|
||||
;;
|
||||
"config")
|
||||
if remove_rule_from_config "$selected_rule"; then
|
||||
delete_success=true
|
||||
# 从状态文件中移除
|
||||
remove_rule_from_state "$selected_rule"
|
||||
fi
|
||||
;;
|
||||
"both")
|
||||
case "$delete_scope" in
|
||||
1)
|
||||
if delete_rule_from_library "$selected_rule"; then
|
||||
delete_success=true
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
if remove_rule_from_config "$selected_rule"; then
|
||||
remove_rule_from_state "$selected_rule"
|
||||
delete_success=true
|
||||
fi
|
||||
;;
|
||||
3)
|
||||
local lib_success=false
|
||||
local config_success=false
|
||||
|
||||
if delete_rule_from_library "$selected_rule"; then
|
||||
lib_success=true
|
||||
fi
|
||||
|
||||
if remove_rule_from_config "$selected_rule"; then
|
||||
remove_rule_from_state "$selected_rule"
|
||||
config_success=true
|
||||
fi
|
||||
|
||||
if [[ "$lib_success" == true ]] || [[ "$config_success" == true ]]; then
|
||||
delete_success=true
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log_error "无效的删除范围选择"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "$delete_success" == true ]]; then
|
||||
log_success "规则 '$selected_rule' 删除操作完成"
|
||||
|
||||
# 如果删除了配置文件中的规则,询问是否重启服务
|
||||
if [[ "$selected_source" == "config" ]] || [[ "$selected_source" == "both" && ("$delete_scope" == "2" || "$delete_scope" == "3") ]]; then
|
||||
echo ""
|
||||
read -p "是否重启 Hysteria2 服务以应用更改? [y/N]: " restart_service
|
||||
if [[ $restart_service =~ ^[Yy]$ ]]; then
|
||||
if systemctl restart hysteria-server 2>/dev/null; then
|
||||
log_success "服务已重启"
|
||||
else
|
||||
log_warn "服务重启失败,请手动重启"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
rm -f "$temp_state"
|
||||
fi
|
||||
else
|
||||
log_error "规则删除失败"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 从规则库中删除
|
||||
local temp_library="/tmp/rules_delete_$$_$(date +%s).yaml"
|
||||
wait_for_user
|
||||
}
|
||||
|
||||
# 从规则库中删除规则的辅助函数
|
||||
delete_rule_from_library() {
|
||||
local rule_name="$1"
|
||||
local temp_library="/tmp/rules_delete_library_$$_$(date +%s).yaml"
|
||||
local in_target_rule=false
|
||||
local rule_indent=""
|
||||
local rule_found=false
|
||||
|
||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||
if [[ "$line" =~ ^[[:space:]]*${selected_rule}:[[:space:]]*$ ]]; then
|
||||
if [[ "$line" =~ ^[[:space:]]*${rule_name}:[[:space:]]*$ ]]; then
|
||||
in_target_rule=true
|
||||
rule_found=true
|
||||
rule_indent=$(echo "$line" | sed 's/[a-zA-Z].*//')
|
||||
continue
|
||||
elif [[ "$in_target_rule" == true ]]; then
|
||||
@@ -2948,24 +3132,39 @@ delete_outbound_rule_new() {
|
||||
fi
|
||||
done < "$RULES_LIBRARY"
|
||||
|
||||
if mv "$temp_library" "$RULES_LIBRARY"; then
|
||||
log_success "规则 '$selected_rule' 已删除"
|
||||
|
||||
read -p "是否重启 Hysteria2 服务? [y/N]: " restart_service
|
||||
if [[ $restart_service =~ ^[Yy]$ ]]; then
|
||||
if systemctl restart hysteria-server 2>/dev/null; then
|
||||
log_success "服务已重启"
|
||||
else
|
||||
log_warn "服务重启失败,请手动重启"
|
||||
fi
|
||||
if [[ "$rule_found" == true ]]; then
|
||||
if mv "$temp_library" "$RULES_LIBRARY"; then
|
||||
log_success "已从规则库中删除规则 '$rule_name'"
|
||||
return 0
|
||||
else
|
||||
log_error "规则库更新失败"
|
||||
rm -f "$temp_library"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log_error "规则删除失败"
|
||||
log_warn "在规则库中未找到规则 '$rule_name'"
|
||||
rm -f "$temp_library"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
wait_for_user
|
||||
# 从状态文件中移除规则的辅助函数
|
||||
remove_rule_from_state() {
|
||||
local rule_name="$1"
|
||||
local temp_state="${RULES_STATE}.tmp"
|
||||
|
||||
if [[ -f "$RULES_STATE" ]]; then
|
||||
awk -v rule="$rule_name" '
|
||||
$0 == " - " rule { next }
|
||||
{ print }
|
||||
' "$RULES_STATE" > "$temp_state" 2>/dev/null
|
||||
|
||||
if [[ -s "$temp_state" ]]; then
|
||||
mv "$temp_state" "$RULES_STATE" 2>/dev/null || rm -f "$temp_state"
|
||||
else
|
||||
rm -f "$temp_state"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# ===== 并发安全和临时文件管理函数 =====
|
||||
|
||||
Reference in New Issue
Block a user