#!/bin/bash
#验证版本1.0.2更新时间2025/9/5更新心跳验证11月23发布使用
#官方网站b6w.cn
#云更新m.b6w.cn
#shell卡密验证云更新系统对接
#请使用MT管理器终端扩展包环境执行无需root只需MT管理器终端扩展包执行
#云更新策略是只要后台没有勾选强制更新就会让用户选择是否更新
#勾选了就会系统强制自动更新.不给用户选择是否选择更新版本号不一致会强制更新
#覆盖原有的内容为新版本下载链接里面的内容
#后台更新的链接可以填写sh后缀的还有zip后缀的
#远程文件是sh则是直接替换当前文件的内容为新版本
#远程文件是zip压缩包则是下载需手动移动出来执行
#因为有些人说他们是执行so要更新so所以用户的意见添加了新版本
#这样只需把sh和so放在压缩包里面做下载下来会手动移动出来执行新版本
# ===================== 开发者配置选项 =====================
#APP ID 也就是apikey
API_KEY="b3ed4c85130660a7ff8441094fe75671"
#版本号判断更新使用
CURRENT_VERSION="1.0.1"
#新版本更新后是否自动重启脚本执行
#  - 填1：更新替换文件内容后，自动重启脚本执行
#  - 填0：更新替换文件内容后，退出脚本，需用户手动重新执行
AUTO_EXEC_AFTER_UPDATE="1"
#心跳验证时间5分钟，也就是300秒（当前配置为300秒，可按需修改）
#不可低于30秒-否则系统检测到异常会封禁
HEARTBEAT_INTERVAL=300
#服务器无响应-无网络尝试次数(不用管)
HEARTBEAT_RETRY=3

# ======================开发者配置完成-下方代码无需修改======================

API_URL_UPDATE=$(echo "aHR0cHM6Ly9tLmI2dy5jbi9hcGkvYjZ3YXBpeWd4LnBocA==" | base64 -d)
API_URL_VERIFY=$(echo "aHR0cHM6Ly9tLmI2dy5jbi9hcGkvYjZ3YXBpa2V5LnBocA==" | base64 -d)
REPORT_URL=$(echo "aHR0cHM6Ly9tLmI2dy5jbi9hcGkvc2IucGhw" | base64 -d)
SIGN_KEY="必6网.免费的云更新验证系统官方网站部分浏览器显示有风险可以换个浏览器-浏览器搜索b6w.cn"
DEVICE_FILE="/data/local/tmp/.device_code.txt"
BACKUP_DEVICE_FILE="./.device_code.txt"
CARD_KEY_MAIN_FILE="/data/local/tmp/.saved_card_key.txt"
CARD_KEY_BACKUP_FILE="./.saved_card_key.txt"
RETRY_INTERVAL=3
get_device_code() {
    local hardware_id=""
    if [ -z "$hardware_id" ] && [ -f "/sys/class/android_usb/android0/iSerial" ]; then
        hardware_id=$(cat /sys/class/android_usb/android0/iSerial 2>/dev/null | tr -d ' \n\r')
    fi
    if [ -z "$hardware_id" ] && [ -f "/proc/cpuinfo" ]; then
        hardware_id=$(grep -i 'serial' /proc/cpuinfo 2>/dev/null | head -n1 | awk -F: '{print $2}' | tr -d ' \n\r')
    fi
    if [ -z "$hardware_id" ] && command -v getprop &>/dev/null; then
        hardware_id=$(getprop ro.serialno 2>/dev/null | tr -d ' \n\r')
        if [ -z "$hardware_id" ]; then
            hardware_id=$(getprop ro.boot.serialno 2>/dev/null | tr -d ' \n\r')
        fi
    fi
    if [ -z "$hardware_id" ] && [ -f "/sys/class/bluetooth/hci0/address" ]; then
        hardware_id=$(cat /sys/class/bluetooth/hci0/address 2>/dev/null | tr -d ':\n\r')
    fi
    if [ -z "$hardware_id" ] && [ -f "/sys/class/net/wlan0/address" ]; then
        hardware_id=$(cat /sys/class/net/wlan0/address 2>/dev/null | tr -d ':\n\r')
    fi
    if [ -z "$hardware_id" ]; then
        if [ -f "$BACKUP_DEVICE_FILE" ]; then
            hardware_id=$(cat "$BACKUP_DEVICE_FILE" 2>/dev/null | tr -d ' \n\r')
        elif [ -f "$DEVICE_FILE" ]; then
            hardware_id=$(cat "$DEVICE_FILE" 2>/dev/null | tr -d ' \n\r')
        else
            hardware_id=$(date +%s | md5sum | head -c 16)
        fi
    fi
    local fixed_code="$hardware_id"
    if [ ${#fixed_code} -gt 32 ]; then
        fixed_code="${fixed_code:0:32}"
    elif [ ${#fixed_code} -lt 32 ]; then
        fixed_code=$(printf "%-32s" "$fixed_code" | tr ' ' '0')
    fi
    if ! echo "$fixed_code" > "$BACKUP_DEVICE_FILE" 2>/dev/null; then
        if echo "$fixed_code" > "$DEVICE_FILE" 2>/dev/null; then
            DEVICE_FILE="$DEVICE_FILE"
        else
            echo "[警告] 设备码文件写入失败，临时生效" >&2
        fi
    else
        DEVICE_FILE="$BACKUP_DEVICE_FILE"
    fi
    chmod 600 "$DEVICE_FILE" 2>/dev/null

    echo "$fixed_code"
}
DEVICE_CODE=$(get_device_code)
[ -z "$DEVICE_CODE" ] && { echo "设备码生成失败" >&2; exit 1; }

request_with_retry() {
    local url="$1"
    local data="$2"
    local retry_count=1

    while true; do
        local response=$(curl -s --connect-timeout 10 -X POST "$url" \
            -H "Content-Type: application/json" \
            -d "$data")

        if [ $? -eq 0 ] && [ -n "$response" ]; then
            echo "$response"
            return 0
        else
            echo "[重试] 接口请求失败（第$retry_count次），$RETRY_INTERVAL秒后重试..."
            sleep $RETRY_INTERVAL
            retry_count=$((retry_count + 1))
        fi
    done
}

extract_field() {
    local key="$1"
    local json="$2"
    echo "$json" | grep -o "\"$key\":\"[^\"]*\"" | sed "s/\"$key\":\"//;s/\"//;s/^[[:space:]]*//;s/[[:space:]]*$//"
}

extract_boolean() {
    local key="$1"
    local json="$2"
    echo "$json" | sed -n "s/.*\"$key\"\s*:\s*\(\(true\)\|\(false\)\).*/\1/p"
}

check_update() {
    echo "===== 开始云更新检查 ====="

    local verify_data='{"action":"verify_api_key", "api_key":"'$API_KEY'"}'
    local verify_response=$(request_with_retry "$API_URL_UPDATE" "$verify_data")
    local app_id=$(extract_field "app_id" "$verify_response")

    if [ -z "$app_id" ]; then
        local error_msg=$(extract_field "error" "$verify_response")
        echo "[错误] 更新验证失败：$error_msg"
        return 1
    fi
    echo "[成功] 应用ID：$app_id"

    local config_data='{"action":"get_config", "app_id":"'$app_id'"}'
    local config_response=$(request_with_retry "$API_URL_UPDATE" "$config_data")

    local announcement=$(extract_field "announcement" "$config_response")
    local latest_version=$(extract_field "latest_version" "$config_response")
    local update_url=$(extract_field "update_url" "$config_response")
    local force_update=$(extract_boolean "force_update" "$config_response")

    local force_update_cn="否"
    [ "$force_update" = "true" ] && force_update_cn="是"

    echo -e "\n[配置信息]:"
    echo -n "  公告内容："
    if [ -n "$announcement" ]; then
        echo -e "$announcement"
    else
        echo "无公告"
    fi
    echo "  当前版本：$CURRENT_VERSION（本地）"
    echo "  最新版本：$latest_version（云端）"
    echo "  是否强制更新：$force_update_cn"
    echo "  开发者更新配置-更新后自动执行：$( [ "$AUTO_EXEC_AFTER_UPDATE" = "1" ] && echo "是" || echo "否" )"

    update_url=$(echo "$update_url" | sed 's/\\\//\//g')

    if [ "$latest_version" != "$CURRENT_VERSION" ] && [ -n "$update_url" ] && [ "$latest_version" != "" ]; then
        echo -e "\n[发现新版本] $latest_version"
        
        if ! command -v curl &> /dev/null; then
            echo "[错误] 缺少curl工具，请安装后重试"
            exit 1
        fi

        if [ "$force_update" = "true" ]; then
            echo "[强制更新] 必须更新才能继续使用！"
            update_action=1
        else
            echo "[非强制更新] 发现新版本，是否更新？（1=更新，0=不更新，默认0）"
            read -p "请输入选择（1/0）：" user_choice
            if [ -z "$user_choice" ]; then
                user_choice=0
            fi
            if [ "$user_choice" -eq 1 ]; then
                echo "用户选择：执行更新"
                update_action=1
            else
                echo "用户选择：不更新，继续执行后续流程"
                update_action=0
                rm -f "$new_file_path" 2>/dev/null
                return 0
            fi
        fi

        if [ $update_action -eq 1 ]; then
            local script_path=$(cd "$(dirname "$0")" || exit; pwd)
            local script_name=$(basename "$0")
            local new_file_path="${script_path}/temp_update_file"

            while true; do
                if curl -fL "$update_url" -o "$new_file_path" &> /dev/null; then
                    break
                else
                    echo "[重试] 更新文件下载失败，$RETRY_INTERVAL秒后重试..."
                    sleep $RETRY_INTERVAL
                fi
            done

            local file_ext=$(echo "$update_url" | awk -F. '{print $NF}' | tr 'A-Z' 'a-z' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
            echo "[更新文件信息] 后缀：$file_ext"

            if [ "$file_ext" = "zip" ]; then
                echo "[更新处理] 识别ZIP文件，生成唯一文件名（保留所有旧文件）"
                local random_str=$(date +%s%N | md5sum | head -c 8)
                local zip_file_name="${script_name%.sh}-${latest_version}-${random_str}.zip"
                local zip_file_path="${script_path}/${zip_file_name}"
            
                if [ -f "$zip_file_path" ]; then
                    echo "[提示] 极端情况：文件名已存在，重新生成随机字符..."
                    random_str=$(date +%s%N | md5sum | head -c 8)
                    zip_file_name="${script_name%.sh}-${latest_version}-${random_str}.zip"
                    zip_file_path="${script_path}/${zip_file_name}"
                fi

                if cat "$new_file_path" > "$0"; then
                    mv -f "$0" "$zip_file_path"
                    echo "[成功] ZIP更新完成：$zip_file_path"
                    echo "[提示] 所有旧版本ZIP文件已完整保留，新文件通过版本号+随机字符区分"
                    echo "[提示] ZIP文件无法自动执行，已退出"
                    rm -f "$new_file_path"
                    exit 0
                else
                    echo "[错误] ZIP文件内容替换失败"
                    rm -f "$new_file_path"
                    exit 1
                fi
            else
                echo "[更新处理] 识别非ZIP文件，覆盖更新并准备自动执行"
                local backup_script_path="${script_path}/${script_name}.bak"
                cp -f "$0" "$backup_script_path" 2>/dev/null
                if cat "$new_file_path" > "$0"; then
                    chmod +x "$0"
                    echo "[成功] 脚本更新至 $latest_version（旧脚本已备份为 ${script_name}.bak）"
                    rm -f "$new_file_path"
                    if [ "$AUTO_EXEC_AFTER_UPDATE" = "1" ]; then
                        echo "按配置：立即自动执行更新后的脚本..."
                        exec bash "$0"
                        echo "[警告] 自动执行触发失败，请手动运行 $0"
                        exit 1
                    else
                        echo "按配置：不自动执行，请手动重启 $0"
                        exit 0
                    fi
                else
                    echo "[错误] 非ZIP文件更新失败，恢复旧脚本..."
                    cp -f "$backup_script_path" "$0" 2>/dev/null
                    rm -f "$new_file_path" "$backup_script_path"
                    exit 1
                fi
            fi

        fi

    else
        if [ "$latest_version" = "$CURRENT_VERSION" ]; then
            echo -e "\n[状态] 本地版本（$CURRENT_VERSION）与云端版本（$latest_version）一致，无需更新"
        elif [ -z "$update_url" ]; then
            echo -e "\n[状态] 虽有新版本（$latest_version），但云端未配置更新链接，无法更新"
        else
            echo -e "\n[状态] 当前已是最新版本"
        fi
    fi

    echo -e "\n===== 更新检查完成 ====="
}

decode_unicode() {
    local str="$1"
    awk -v str="$str" 'BEGIN {
        while (match(str, /\\u([0-9a-fA-F]{4})/, arr)) {
            c = sprintf("%c", strtonum("0x" arr[1]))
            gsub(/\\u[0-9a-fA-F]{4}/, c, str)
        }
        print str
    }'
}

generate_sign() {
    local data="$1"
    local salt="$2"
    local timestamp="$3"
    echo -n "${data}${salt}${timestamp}${SIGN_KEY}" | md5sum | awk '{print $1}'
}

report_tampering() {
    local request_params="$1"
    local tampered_response="$2"
    local timestamp="$3"
    local client_ip=$(curl -s --connect-timeout 5 http://icanhazip.com 2>/dev/null || \
                      curl -s --connect-timeout 5 http://ip.cn/ip 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' || \
                      echo "未知IP")
    client_ip=$(echo "$client_ip" | tr -d '\n\r')

    req_escaped=$(echo "$request_params" | sed 's/\\/\\\\/g')
    resp_escaped=$(echo "$tampered_response" | sed 's/\\/\\\\/g')
    req_escaped=$(echo "$req_escaped" | sed 's/"/\\"/g')
    resp_escaped=$(echo "$resp_escaped" | sed 's/"/\\"/g')
    req_escaped=$(echo "$req_escaped" | sed ':a;N;$!ba;s/\n/\\n/g')
    resp_escaped=$(echo "$resp_escaped" | sed ':a;N;$!ba;s/\n/\\n/g')
    req_escaped=$(echo "$req_escaped" | sed 's/\r/\\r/g; s/\t/\\t/g')
    resp_escaped=$(echo "$resp_escaped" | sed 's/\r/\\r/g; s/\t/\\t/g')

    report_data="{\"ip\":\"$client_ip\",\"timestamp\":\"$timestamp\",\"request_params\":\"$req_escaped\",\"tampered_response\":\"$resp_escaped\"}"
    report_result=$(curl -s --connect-timeout 10 -X POST "$REPORT_URL" \
        -H "Content-Type: application/json" -d "$report_data")
    result_msg=$(echo "$report_result" | sed -n 's/.*"message":"\([^"]*\)".*/\1/p' | decode_unicode)
    echo "数据已记录上传结果：${result_msg:-篡改数据已上传}"
}

verify_card_key() {
    echo -e "\n===== 开始卡密验证 ====="

    local CARD_KEY=""
    # 修复：先读当前目录备份文件（优先级高），再读主路径文件
    if [ -f "$CARD_KEY_BACKUP_FILE" ]; then
        CARD_KEY=$(cat "$CARD_KEY_BACKUP_FILE" 2>/dev/null | tr -d ' \n\r')
        if [ -n "$CARD_KEY" ]; then
            echo "[自动登录] 从当前目录读取到卡密，自动验证..."
            goto_verify=true
        else
            rm -f "$CARD_KEY_BACKUP_FILE"
            CARD_KEY=""
        fi
    fi

    # 若当前目录无有效卡密，再读主路径文件
    if [ -z "$CARD_KEY" ] && [ -f "$CARD_KEY_MAIN_FILE" ]; then
        CARD_KEY=$(cat "$CARD_KEY_MAIN_FILE" 2>/dev/null | tr -d ' \n\r')
        if [ -n "$CARD_KEY" ]; then
            echo "[自动登录] 从主路径读取到卡密，自动验证..."
        else
            rm -f "$CARD_KEY_MAIN_FILE"
            CARD_KEY=""
        fi
    fi

    while true; do
        if [ -z "$CARD_KEY" ]; then
            read -p "请输入卡密：" CARD_KEY
            if [ -z "$CARD_KEY" ]; then
                echo "卡密不能为空，请重新输入"
                continue
            fi
        fi

        TIMESTAMP=$(date +%s)
        REQUEST_PARAMS=$(printf '{"api_key":"%s","key":"%s","device_code":"%s","timestamp":"%s"}' \
            "$API_KEY" "$CARD_KEY" "$DEVICE_CODE" "$TIMESTAMP")

        RESPONSE=$(request_with_retry "$API_URL_VERIFY" "$REQUEST_PARAMS")

        CODE=$(echo "$RESPONSE" | sed -n 's/.*"code":[[:space:]]*\([0-9]*\).*/\1/p; s/.*"code"[[:space:]]*:[[:space:]]*\([0-9]*\),.*/\1/p' | head -n1)
        MESSAGE_RAW=$(echo "$RESPONSE" | sed -n 's/.*"message":[[:space:]]*"\([^"]*\)".*/\1/p; s/.*"message":[[:space:]]*"\([^"]*\)",.*/\1/p' | head -n1)
        MESSAGE=$(decode_unicode "$MESSAGE_RAW")
        DATA=$(echo "$RESPONSE" | sed -n 's/.*"data":[[:space:]]*"\([^"]*\)".*/\1/p' | head -n1)
        SALT=$(echo "$RESPONSE" | sed -n 's/.*"salt":[[:space:]]*"\([^"]*\)".*/\1/p' | head -n1)
        SERVER_SIGN=$(echo "$RESPONSE" | sed -n 's/.*"sign":[[:space:]]*"\([^"]*\)".*/\1/p' | head -n1)

        if [ "$CODE" -eq 200 ] && [ -n "$DATA" ] && [ -n "$SALT" ] && [ -n "$SERVER_SIGN" ]; then
            CLIENT_SIGN=$(generate_sign "$DATA" "$SALT" "$TIMESTAMP")
            if [ "$CLIENT_SIGN" != "$SERVER_SIGN" ]; then
                echo "验证失败：数据被篡改.请勿非法破解.严重的提交至公安机关处理"
                report_tampering "$REQUEST_PARAMS" "$RESPONSE" "$TIMESTAMP"
                CARD_KEY=""
                continue
            fi

            RAW_DATA=$(echo -n "$DATA" | base64 -d 2>/dev/null)
            EXPIRES_AT=$(echo "$RAW_DATA" | sed -n 's/.*"expires_at":[[:space:]]*"\([^"]*\)".*/\1/p; s/.*"expires_at":"\([^"]*\)".*/\1/p' | head -n1 | tr -d ' \n\r}')
            USED_DEVICES=$(echo "$RAW_DATA" | sed -n 's/.*"used_devices":[[:space:]]*\([0-9]*\).*/\1/p; s/.*"used_devices":\([0-9]*\).*/\1/p' | head -n1 | tr -d ' \n\r,}')
            MAX_DEVICES=$(echo "$RAW_DATA" | sed -n 's/.*"max_devices":[[:space:]]*\([0-9]*\).*/\1/p; s/.*"max_devices":\([0-9]*\).*/\1/p' | head -n1 | tr -d ' \n\r,}')

            if [ -n "$EXPIRES_AT" ] && [ -n "$USED_DEVICES" ] && [ -n "$MAX_DEVICES" ]; then
                # 保存卡密：优先当前目录（无需root），失败再试主路径
                if echo "$CARD_KEY" > "$CARD_KEY_BACKUP_FILE" 2>/dev/null; then
                    chmod 600 "$CARD_KEY_BACKUP_FILE"
                    echo "[自动登录] 卡密已保存到当前目录（$CARD_KEY_BACKUP_FILE），下次自动验证"
                elif echo "$CARD_KEY" > "$CARD_KEY_MAIN_FILE" 2>/dev/null; then
                    chmod 600 "$CARD_KEY_MAIN_FILE"
                    echo "[自动登录] 卡密已保存到主路径（$CARD_KEY_MAIN_FILE），下次自动验证"
                else
                    echo "[警告] 卡密保存失败，下次需重新输入" >&2
                fi
                export GLOBAL_CARD_KEY="$CARD_KEY"
                export GLOBAL_EXPIRES_AT="$EXPIRES_AT"
                export GLOBAL_USED_DEVICES="$USED_DEVICES"
                export GLOBAL_MAX_DEVICES="$MAX_DEVICES"
                break
            else
                echo "验证失败：数据不完整，请重新输入"
                CARD_KEY=""
            fi
        else
            [ -z "$MESSAGE" ] && MESSAGE="未知错误"
            echo "验证失败：$MESSAGE，请重新输入"
            CARD_KEY=""
            # 清除无效卡密文件
            [ -f "$CARD_KEY_MAIN_FILE" ] && rm -f "$CARD_KEY_MAIN_FILE"
            [ -f "$CARD_KEY_BACKUP_FILE" ] && rm -f "$CARD_KEY_BACKUP_FILE"
        fi
    done
}

heartbeat_verify() {
    echo -e "\n===== 心跳验证已启动（间隔$HEARTBEAT_INTERVAL秒） ====="
    while true; do
        sleep $HEARTBEAT_INTERVAL
        echo -e "\n[心跳] （$(date "+%Y-%m-%d %H:%M:%S")）"

        local card_key="$GLOBAL_CARD_KEY"
        local device_code="$DEVICE_CODE"

        if [ -z "$card_key" ] || [ -z "$device_code" ]; then
            echo "[心跳] 卡密/设备码缺失，强制中断脚本"
            exit 1
        fi

        local TIMESTAMP=$(date +%s)
        local REQUEST_PARAMS=$(printf '{"api_key":"%s","key":"%s","device_code":"%s","timestamp":"%s"}' \
            "$API_KEY" "$card_key" "$device_code" "$TIMESTAMP")

        local retry_count=1
        local RESPONSE=""
        while [ $retry_count -le $HEARTBEAT_RETRY ]; do
            RESPONSE=$(curl -s --connect-timeout 10 -X POST "$API_URL_VERIFY" \
                -H "Content-Type: application/json" -d "$REQUEST_PARAMS")
            if [ $? -eq 0 ] && [ -n "$RESPONSE" ]; then
                break
            else
                echo "[心跳重试] 请求失败（第$retry_count次），$RETRY_INTERVAL秒后重试..."
                sleep $RETRY_INTERVAL
                retry_count=$((retry_count + 1))
            fi
        done

        if [ -z "$RESPONSE" ]; then
            echo "[心跳] 服务器无响应，本次跳过，下次继续验证(注此提示不影响你正常的源代码脚本执行)"
            continue
        fi

        local CODE=$(echo "$RESPONSE" | sed -n 's/.*"code":[[:space:]]*\([0-9]*\).*/\1/p; s/.*"code"[[:space:]]*:[[:space:]]*\([0-9]*\),.*/\1/p' | head -n1)
        local MESSAGE_RAW=$(echo "$RESPONSE" | sed -n 's/.*"message":[[:space:]]*"\([^"]*\)".*/\1/p; s/.*"message":[[:space:]]*"\([^"]*\)",.*/\1/p' | head -n1)
        local MESSAGE=$(decode_unicode "$MESSAGE_RAW")

        if [ "$CODE" -eq 200 ]; then
            echo "[心跳] 验证成功(注此提示不影响你正常的源代码脚本执行)"
        else
            echo "[心跳] 卡密验证失败：$MESSAGE"
            echo "[心跳] 强制中断脚本运行"
            exit 1
        fi
    done
}

start_heartbeat_in_background() {
    heartbeat_verify &
    # 记录心跳进程ID，确保脚本退出时心跳也退出
    HEARTBEAT_PID=$!
    trap 'kill $HEARTBEAT_PID 2>/dev/null' EXIT
}

check_update
verify_card_key
echo -e "\n卡密验证成功"
echo "到期时间：$GLOBAL_EXPIRES_AT"
echo "设备限制：已用$GLOBAL_USED_DEVICES台，共$GLOBAL_MAX_DEVICES台"

# 启动后台心跳验证
start_heartbeat_in_background

# ===================== 你的源代码填写区域 =====================
#卡密验证之后则会执行你的源代码

#!/system/bin/sh

# 蓝猫助手 - 多文件下载注入工具
# 支持多种配置，便于二次修改

# 颜色定义
RED='\033[1;91m'
GREEN='\033[1;92m'
YELLOW='\033[1;93m'
BLUE='\033[1;94m'
CYAN='\033[1;96m'
WHITE='\033[1;97m'
PURPLE='\033[1;95m'
NC='\033[0m'

# 图标
CHECK='✓'
CROSS='✗'
ARROW='➜'
TRIANGLE='▶'
STAR='★'

# 清屏
clear


cat << "EOF"
                                  
    ██████╗ █████╗ ████████╗      
   ██╔════╝██╔══██╗╚══██╔══╝      
   ██║ 12    ███████║   ██║         
   ██║     ██╔══██║   ██║         
   ╚██████╗██║  ██║   ██║         
    ╚═════╝╚═╝  ╚═╝   ╚═╝         
                                  
EOF
# 简洁标题
echo -e "${CYAN}╭─────────────────────────────────────╮${NC}"
echo -e "${CYAN}│${NC}        ${WHITE}蓝猫助手${NC}         ${CYAN}│${NC}"
echo -e "${CYAN}╰─────────────────────────────────────╯${NC}"
echo ""

# 系统信息
echo -e "${BLUE}${TRIANGLE}${NC} ${WHITE}系统信息${NC}"

# 获取安卓版本
android_version=$(getprop ro.build.version.release 2>/dev/null || echo "未知")
android_sdk=$(getprop ro.build.version.sdk 2>/dev/null || echo "0")
echo -e "  ${ARROW} 安卓版本: ${GREEN}Android ${android_version}${NC}"
echo -e "  ${ARROW} SDK版本:  ${GREEN}${android_sdk}${NC}"

# 获取手机型号
device_model=$(getprop ro.product.model 2>/dev/null || echo "未知")
echo -e "  ${ARROW} 手机型号: ${YELLOW}${device_model}${NC}"

# 获取设备品牌
device_brand=$(getprop ro.product.brand 2>/dev/null || echo "未知")
echo -e "  ${ARROW} 设备品牌: ${CYAN}${device_brand}${NC}"

# 获取内核版本
kernel_version=$(uname -r 2>/dev/null | cut -d'-' -f1)
echo -e "  ${ARROW} 内核版本: ${CYAN}${kernel_version}${NC}"

# 获取当前时间
current_time=$(date '+%Y-%m-%d %H:%M:%S')
echo -e "  ${ARROW} 当前时间: ${CYAN}${current_time}${NC}"

echo -e "  ${ARROW} 官方频道: ${CYAN}@BlueCatB${NC}"

echo -e "  ${ARROW} 官方群聊: ${CYAN}1051095950${NC}"

# 检查you.sh是否存在
YOU_SH="$(dirname "$0")/you.sh"
# 检查是否安卓11以下
if [ "$android_sdk" -lt 30 ]; then
    echo -e "  ${ARROW} 使用环境: ${GREEN}普通Shell (安卓11以下)${NC}"
    USE_YOUSH=false
else
    if [ -f "$YOU_SH" ]; then
        echo -e "  ${ARROW} 使用环境: ${GREEN}Shizuku${NC}"
        USE_YOUSH=true
    else
        echo -e "  ${ARROW} 使用环境: ${YELLOW}普通模式${NC}"
        USE_YOUSH=false
    fi
fi

echo ""

# 分隔线
echo -e "${CYAN}═════════════════════════════════════════${NC}"
echo ""

# ===========================================
# 配置文件区域 - 可以在这里添加更多下载任务
# ===========================================

# 任务列表配置
# 格式: ["任务名称"]="下载链接|目标目录|显示名称"
declare -A TASKS=(
    ["task1"]="https://www.cccimg.com/down.php/8ec5235538b24584aa6892462c6f23f3.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/Paks/|超广角(14590)"
    ["task2"]="https://www.cccimg.com/down.php/66cb66f6beeb08e2d4162daeb596f34f.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/Paks/|微加速广角(14590)"
    ["task3"]="https://www.cccimg.com/down.php/8472760fbeed8fefaaba6093885bc3dd.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/Paks/|实体范围(14590)" 
    ["task4"]="https://www.cccimg.com/down.php/4296373b8f239e29bff247196e988d76.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/Paks/|全局美化(14590)"
    ["task5"]="https://www.cccimg.com/down.php/168dd86d75f65b4f5143fe6be28c80ae.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/Paks/|人物天线(14590)"       
    ["task6"]="https://www.cccimg.com/down.php/e4741fe63c942d71b039f2ea2a8137e3.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/Paks/|原版文件(14590)"            
    ["task7"]="https://www.cccimg.com/down.php/12d6a1e91cca34c08b71f19fb84e7a1f.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/Paks/|度假岛除草"
    ["task8"]="https://www.cccimg.com/down.php/5c850bd17cc01d0ac7833e88da8eedb2.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/Paks/|度假岛黑天水泥地"    
    ["task9"]="https://www.cccimg.com/down.php/a85e3cc532344c205e66bc361df3e00e.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/Config/Android/|辅助瞄准增强(配置文件)"
    ["task10"]="https://www.cccimg.com/down.php/200ff6cc9afaaac05a8dc45e6e5157ec.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/SaveGames/|动态范围(配置文件)"
    ["task11"]="https://www.cccimg.com/down.php/5c8687ec1c77ea06495b4e155b4c4eff.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/SaveGames/|静态范围(配置文件)"
    ["task12"]="https://www.cccimg.com/down.php/6fddb869b385a910a6667bed38c7a0d9.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/Paks/|功能文件一(14515)"
    ["task13"]="https://www.cccimg.com/down.php/a96ec51e660da7bfd95d8b2467a9ae4c.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/Paks/|功能文件二(14515)"
    ["task14"]="https://www.cccimg.com/down.php/bae924f36a67c4faec77015bcb86128b.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/Paks/|功能文件三(14515)"
    ["task15"]="https://www.cccimg.com/down.php/fac75527178eede9d420089696786015.zip|/storage/emulated/0/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/Paks/|原版文件(14515)"
)

# 定义任务顺序
TASK_ORDER=("task1" "task2" "task3" "task4" "task5" "task6" "task7" "task8" "task9" "task10" "task11" "task12" "task13" "task14" "task15")

# 下载工具优先级
DOWNLOAD_TOOLS=("wget" "curl")
# 解压工具优先级
EXTRACT_TOOLS=("unzip" "busybox")
# 临时目录
TEMP_DIR="/sdcard/Download"
[ ! -d "$TEMP_DIR" ] && TEMP_DIR="/storage/emulated/0/Download"
[ ! -d "$TEMP_DIR" ] && TEMP_DIR="/data/local/tmp"

# ===========================================
# 函数定义
# ===========================================

# 通过you.sh执行命令（不显示输出）- 安卓11+专用
exec_via_yoush_silent() {
    local command="$1"
    if [ "$USE_YOUSH" = true ] && [ -f "$YOU_SH" ]; then
        echo "$command" | sh "$YOU_SH" > /dev/null 2>&1
        return $?
    else
        eval "$command" > /dev/null 2>&1
        return $?
    fi
}

# 通过you.sh执行命令（有选择地显示输出）- 安卓11+专用
exec_via_yoush() {
    local command="$1"
    if [ "$USE_YOUSH" = true ] && [ -f "$YOU_SH" ]; then
        echo "$command" | sh "$YOU_SH"
        return $?
    else
        eval "$command"
        return $?
    fi
}

# 通用执行命令函数
exec_cmd() {
    local command="$1"
    local silent="$2"
    
    if [ "$USE_YOUSH" = true ] && [ -f "$YOU_SH" ]; then
        if [ "$silent" = "silent" ]; then
            echo "$command" | sh "$YOU_SH" > /dev/null 2>&1
        else
            echo "$command" | sh "$YOU_SH"
        fi
    else
        if [ "$silent" = "silent" ]; then
            eval "$command" > /dev/null 2>&1
        else
            eval "$command"
        fi
    fi
    return $?
}

# 检查命令是否存在
check_command() {
    for cmd in "$@"; do
        if command -v "$cmd" > /dev/null 2>&1; then
            echo "$cmd"
            return 0
        fi
    done
    return 1
}

# 显示菜单
show_menu() {
    echo -e "${BLUE}${TRIANGLE}${NC} ${WHITE}请选择要执行的任务${NC}"
    echo ""
    
    local index=1
    for task_name in "${TASK_ORDER[@]}"; do
        if [ -n "${TASKS[$task_name]}" ]; then
            # 解析任务配置获取显示名称
            local config="${TASKS[$task_name]}"
            IFS='|' read -r url dest display_name <<< "$config"
            [ -z "$display_name" ] && display_name="$task_name"
            
            # 格式化序号，两位对齐
            printf "  ${CYAN}%2d.${NC} ${WHITE}%s${NC}\n" "$index" "$display_name"
            ((index++))
        fi
    done
    
    echo ""
    echo -e "  ${CYAN}a.${NC} ${WHITE}全部执行${NC}"
    echo -e "  ${CYAN}m.${NC} ${WHITE}多选执行 (如: 1 3 5)${NC}"
    echo -e "  ${CYAN}q.${NC} ${WHITE}退出${NC}"
    echo ""
}

# 获取任务列表
get_task_list() {
    echo "${TASK_ORDER[@]}"
}

# 通过索引获取任务名称
get_task_by_index() {
    local index="$1"
    local task_list=($(get_task_list))
    
    if [ $index -ge 1 ] && [ $index -le ${#task_list[@]} ]; then
        echo "${task_list[$((index-1))]}"
        return 0
    else
        return 1
    fi
}

# 解析任务配置
parse_task() {
    local task_name="$1"
    local config="${TASKS[$task_name]}"
    
    if [ -z "$config" ]; then
        echo -e "${RED}错误: 任务 '${task_name}' 配置不存在${NC}"
        return 1
    fi
    
    # 分割配置: 下载链接|目标目录|显示名称
    IFS='|' read -r url dest display_name <<< "$config"
    
    # 如果没有指定显示名称，使用任务名称
    [ -z "$display_name" ] && display_name="$task_name"
    
    # 返回结果
    CURRENT_TASK_NAME="$task_name"
    CURRENT_DISPLAY_NAME="$display_name"
    CURRENT_URL="$url"
    CURRENT_DEST="$dest"
    
    # 创建临时文件名
    local timestamp=$(date +%s)
    local random=$((RANDOM % 1000))
    CURRENT_TEMP_FILE="${TEMP_DIR}/download_${task_name}_${timestamp}_${random}.zip"
    
    return 0
}

# 显示任务信息
show_task_info() {
    echo -e "${BLUE}${TRIANGLE}${NC} ${WHITE}任务信息${NC}"
    echo -e "  ${ARROW} 任务名称: ${YELLOW}${CURRENT_DISPLAY_NAME}${NC}"
    echo -e "  ${ARROW} 目标目录: ${YELLOW}${CURRENT_DEST}${NC}"
    echo ""
}

# 显示进度条
show_progress() {
    local percent="$1"
    local task="$2"
    local width=30
    local bar_length=$((percent * width / 100))
    local bar=""
    
    for ((i=0; i<bar_length; i++)); do
        bar="${bar}█"
    done
    for ((i=bar_length; i<width; i++)); do
        bar="${bar}░"
    done
    
    printf "\r  ${ARROW} ${task}进度: [${GREEN}%s${NC}] ${CYAN}%3d%%${NC}" "$bar" "$percent"
}

# 下载文件
download_file() {
    local url="$1"
    local output_file="$2"
    
    echo -e "  ${ARROW} 正在连接服务器..."
    
    # 检查下载工具
    local download_tool=$(check_command "${DOWNLOAD_TOOLS[@]}")
    if [ -z "$download_tool" ]; then
        echo -e "  ${ARROW} ${RED}✗ 下载失败${NC}"
        return 1
    fi
    
    # 创建临时目录
    exec_cmd "mkdir -p \"$(dirname "$output_file")\"" "silent"
    
    # 开始下载
    if [ "$download_tool" = "wget" ]; then
        wget -q -O "$output_file" "$url" 2>&1 | \
        while IFS= read -r line; do
            if echo "$line" | grep -q "[0-9]*%"; then
                local percent=$(echo "$line" | grep -o "[0-9]*%" | head -n1 | tr -d '%')
                [ -z "$percent" ] && percent=0
                show_progress "$percent" "下载"
            fi
        done
    elif [ "$download_tool" = "curl" ]; then
        curl -L -o "$output_file" "$url" 2>&1 | \
        while IFS= read -r line; do
            if echo "$line" | grep -q "[0-9]*\.[0-9]*%"; then
                local percent=$(echo "$line" | grep -o "[0-9]*\.[0-9]*%" | head -n1 | cut -d. -f1)
                [ -z "$percent" ] && percent=0
                show_progress "$percent" "下载"
            fi
        done
    fi
    
    # 确保显示100%
    show_progress 100 "下载"
    echo ""
    
    # 检查下载结果
    if [ $? -eq 0 ] && [ -f "$output_file" ]; then
        return 0
    else
        echo -e "  ${ARROW} ${RED}✗ 下载失败${NC}"
        return 1
    fi
}

# 解压文件（通过you.sh执行，不显示详细信息）
extract_file_silent() {
    local input_file="$1"
    local output_dir="$2"
    
    # 检查解压工具
    local extract_tool=$(check_command "${EXTRACT_TOOLS[@]}")
    if [ -z "$extract_tool" ]; then
        echo -e "  ${ARROW} ${RED}✗ 解压失败${NC}"
        return 1
    fi
    
    # 创建目标目录
    exec_cmd "mkdir -p \"$output_dir\"" "silent"
    
    # 构建解压命令
    local unzip_cmd=""
    if [ "$extract_tool" = "unzip" ]; then
        unzip_cmd="unzip -oq \"$input_file\" -d \"$output_dir\" 2>/dev/null"
    elif [ "$extract_tool" = "busybox" ]; then
        unzip_cmd="busybox unzip -oq \"$input_file\" -d \"$output_dir\" 2>/dev/null"
    else
        return 1
    fi
    
    # 执行解压命令
    if exec_cmd "$unzip_cmd" "silent"; then
        return 0
    else
        return 1
    fi
}

# 解压文件（带进度显示）
extract_file() {
    local input_file="$1"
    local output_dir="$2"
    
    echo -ne "  ${ARROW} 解压进度: ["
    for ((i=0; i<30; i++)); do
        echo -ne "░"
    done
    echo -ne "] ${CYAN}0%${NC}\r"
    
    # 在后台执行解压
    extract_file_silent "$input_file" "$output_dir" &
    local extract_pid=$!
    
    # 显示进度条动画
    for i in {1..30}; do
        local percent=$((i * 100 / 30))
        local bar_length=$i
        local bar=""
        
        for ((j=0; j<bar_length; j++)); do
            bar="${bar}▓"
        done
        for ((j=bar_length; j<30; j++)); do
            bar="${bar}░"
        done
        
        # 检查解压是否完成
        if ! kill -0 "$extract_pid" 2>/dev/null; then
            break
        fi
        
        printf "  ${ARROW} 解压进度: [${GREEN}%s${NC}] ${CYAN}%3d%%${NC}\r" "$bar" "$percent"
        sleep 0.1
    done
    
    # 等待解压完成
    wait "$extract_pid"
    local result=$?
    
    # 显示完成
    printf "  ${ARROW} 解压进度: [${GREEN}"
    for ((i=0; i<30; i++)); do
        printf "█"
    done
    printf "${NC}] ${CYAN}100%%${NC}\n"
    
    if [ $result -eq 0 ]; then
        return 0
    else
        echo -e "  ${ARROW} ${YELLOW}⚠ 解压过程可能有警告${NC}"
        return 1
    fi
}

# 执行单个任务
execute_task() {
    local task_name="$1"
    
    echo -e "${CYAN}═════════════════════════════════════════${NC}"
    echo -e "${GREEN}${TRIANGLE}${NC} ${WHITE}开始执行任务: ${YELLOW}${CURRENT_DISPLAY_NAME}${NC}"
    
    # 解析任务配置
    if ! parse_task "$task_name"; then
        return 1
    fi
    
    # 显示任务信息
    show_task_info
    
    # 下载文件
    echo -e "  ${ARROW} 开始下载..."
    if ! download_file "$CURRENT_URL" "$CURRENT_TEMP_FILE"; then
        return 1
    fi
    
    # 检查文件大小
    local file_size=0
    if [ -f "$CURRENT_TEMP_FILE" ]; then
        if command -v wc > /dev/null 2>&1; then
            file_size=$(wc -c < "$CURRENT_TEMP_FILE" 2>/dev/null || echo 0)
        elif command -v stat > /dev/null 2>&1; then
            file_size=$(stat -c%s "$CURRENT_TEMP_FILE" 2>/dev/null || stat -f%z "$CURRENT_TEMP_FILE" 2>/dev/null || echo 0)
        fi
    fi
    
    if [ "$file_size" -eq 0 ]; then
        echo -e "  ${ARROW} ${RED}✗ 下载的文件为空${NC}"
        rm -f "$CURRENT_TEMP_FILE" 2>/dev/null
        return 1
    fi
    
    echo -e "  ${ARROW} 文件大小: ${CYAN}$((file_size/1024)) KB${NC}"
    echo ""
    
    # 解压文件
    echo -e "  ${ARROW} 开始解压..."
    if ! extract_file "$CURRENT_TEMP_FILE" "$CURRENT_DEST"; then
        echo -e "  ${ARROW} ${YELLOW}⚠ 解压可能不完整${NC}"
    fi
    
    # 清理临时文件
    rm -f "$CURRENT_TEMP_FILE" 2>/dev/null
    
    echo -e "  ${GREEN}${CHECK}${NC} 任务完成"
    
    return 0
}

# 执行多个任务
execute_multiple_tasks() {
    local task_indices="$1"
    local success_count=0
    local task_array=($task_indices)
    local total_tasks="${#task_array[@]}"
    local current_task=1
    
    echo -e "${BLUE}${TRIANGLE}${NC} ${WHITE}开始执行选中的任务 (共 ${total_tasks} 个)${NC}"
    echo ""
    
    for index in "${task_array[@]}"; do
        if [ $total_tasks -gt 1 ]; then
            echo -e "${WHITE}任务 ${current_task}/${total_tasks} (编号: ${index})${NC}"
        fi
        
        # 获取任务名称
        task_name=$(get_task_by_index "$index")
        if [ -n "$task_name" ]; then
            # 先解析任务获取显示名称
            if parse_task "$task_name"; then
                if execute_task "$task_name"; then
                    ((success_count++))
                fi
            fi
        else
            echo -e "  ${RED}✗ 任务编号 ${index} 无效，跳过${NC}"
        fi
        
        ((current_task++))
        
        # 如果不是最后一个任务，添加间隔
        if [ $current_task -le $total_tasks ]; then
            echo ""
        fi
    done
    
    echo -e "${CYAN}═════════════════════════════════════════${NC}"
    echo ""
    echo -e "${BLUE}${TRIANGLE}${NC} ${WHITE}执行结果${NC}"
    echo -e "  ${ARROW} 总任务数: ${total_tasks}"
    echo -e "  ${ARROW} 成功: ${GREEN}${success_count}${NC}"
    echo -e "  ${ARROW} 失败: ${RED}$((total_tasks - success_count))${NC}"
    echo ""
    
    return $((total_tasks - success_count))
}

# 执行所有任务
execute_all_tasks() {
    local task_list=($(get_task_list))
    local success_count=0
    local total_tasks="${#task_list[@]}"
    local current_task=1
    
    echo -e "${BLUE}${TRIANGLE}${NC} ${WHITE}开始执行所有任务 (共 ${total_tasks} 个)${NC}"
    echo ""
    
    for task_name in "${task_list[@]}"; do
        if [ $total_tasks -gt 1 ]; then
            echo -e "${WHITE}任务 ${current_task}/${total_tasks}${NC}"
        fi
        
        # 先解析任务获取显示名称
        if parse_task "$task_name"; then
            if execute_task "$task_name"; then
                ((success_count++))
            fi
        fi
        
        ((current_task++))
        
        # 如果不是最后一个任务，添加间隔
        if [ $current_task -le $total_tasks ]; then
            echo ""
        fi
    done
    
    echo -e "${CYAN}═════════════════════════════════════════${NC}"
    echo ""
    echo -e "${BLUE}${TRIANGLE}${NC} ${WHITE}执行结果${NC}"
    echo -e "  ${ARROW} 总任务数: ${total_tasks}"
    echo -e "  ${ARROW} 成功: ${GREEN}${success_count}${NC}"
    echo -e "  ${ARROW} 失败: ${RED}$((total_tasks - success_count))${NC}"
    echo ""
    
    return $((total_tasks - success_count))
}

# 检查输入是否为数字
is_number() {
    local num="$1"
    [[ "$num" =~ ^[0-9]+$ ]]
}

# 检查输入是否为多个数字
is_multiple_numbers() {
    local input="$1"
    
    # 如果是空字符串，返回false
    [ -z "$input" ] && return 1
    
    # 检查是否包含空格
    if [[ "$input" =~ [[:space:]] ]]; then
        # 分割输入
        local numbers=($input)
        
        # 检查每个部分是否都是数字
        for num in "${numbers[@]}"; do
            if ! is_number "$num"; then
                return 1
            fi
        done
        return 0
    else
        return 1
    fi
}

# ===========================================
# 主程序
# ===========================================

# 检查任务列表是否为空
if [ ${#TASK_ORDER[@]} -eq 0 ]; then
    echo -e "${RED}错误: 任务列表为空${NC}"
    echo "请在脚本的 TASK_ORDER 数组中添加任务配置"
    echo ""
    exit 1
fi

# 显示菜单
show_menu

# 获取任务总数
task_count=${#TASK_ORDER[@]}

# 读取用户选择
read -p "请输入选择 (1-${task_count}, a, m, q): " choice

# 处理用户选择
if [ -z "$choice" ]; then
    echo -e "${RED}无效的选择${NC}"
    exit 1
elif [[ "$choice" =~ ^[0-9]+$ ]]; then
    # 单个数字输入
    if [ "$choice" -ge 1 ] && [ "$choice" -le "$task_count" ]; then
        # 执行单个任务
        task_name=$(get_task_by_index "$choice")
        if [ -n "$task_name" ]; then
            # 先解析任务获取显示名称
            if parse_task "$task_name"; then
                echo ""
                execute_task "$task_name"
            else
                echo -e "${RED}解析任务失败${NC}"
                exit 1
            fi
        else
            echo -e "${RED}无效的选择${NC}"
            exit 1
        fi
    else
        echo -e "${RED}无效的选择${NC}"
        exit 1
    fi
elif [[ "$choice" =~ ^[0-9]+[[:space:]]+[0-9]+.*$ ]]; then
    # 多个数字输入
    echo ""
    execute_multiple_tasks "$choice"
elif [[ "$choice" =~ ^[Aa]$ ]]; then
    # 执行所有任务
    echo ""
    execute_all_tasks
elif [[ "$choice" =~ ^[Mm]$ ]]; then
    # 多选模式
    echo ""
    echo -e "${BLUE}${TRIANGLE}${NC} ${WHITE}多选模式${NC}"
    echo -e "  ${ARROW} 请输入任务编号，用空格分隔"
    echo -e "  ${ARROW} 例如: 1 3 5 7"
    echo -e "  ${ARROW} 或者: 2 4 6 8 10"
    echo ""
    read -p "请输入任务编号: " multi_choice
    
    if is_multiple_numbers "$multi_choice"; then
        echo ""
        execute_multiple_tasks "$multi_choice"
    else
        echo -e "${RED}错误: 请输入有效的任务编号，用空格分隔${NC}"
        exit 1
    fi
elif [[ "$choice" =~ ^[Qq]$ ]]; then
    # 退出程序
    echo -e "${CYAN}退出程序${NC}"
    exit 0
else
    echo -e "${RED}无效的选择${NC}"
    exit 1
fi

echo -e "${CYAN}═════════════════════════════════════════${NC}"
echo ""
echo -e "${GREEN}${CHECK}${NC} ${WHITE}所有操作已完成！${NC}"
echo ""
echo -e "${BLUE}使用必看:${NC}"
echo -e "  ${CYAN}1.${NC} 后面有数字比如14950都是同一个文件不能一起用"
echo -e "  ${CYAN}2.${NC} 除了配置文件其他都要配端口为了稳定性"
echo -e "  ${CYAN}3.${NC} 没效果自己检查自身问题"
echo ""
echo -e "${YELLOW}注意: 使用改文件有封号风险，请谨慎操作${NC}"
echo ""
echo -e "${CYAN}═════════════════════════════════════════${NC}"
echo -e "${CYAN}蓝猫助手 - 任务执行结束${NC}"
echo ""

#注：源代码执行期间，心跳会在后台每隔$HEARTBEAT_INTERVAL秒自动验证


# ===================== 上方填写你的源代码 =====================

# 等待用户源代码执行完成（若用户代码是持续运行的，此句可省略）
wait
