#!/bin/bash

# Minecraft Java 方便式一键脚本

# 全局变量定义

# 模式标志
IN_EDIT_MODE="false"
IN_LOG_VIEW_MODE="false"
CURRENT_SERVER=""
CURRENT_MENU=""
# 管理器版本
MANAGER_VERSION="1.0.3"

# 下载状态标志
_download_in_progress="false"
_download_cancelled="false"

# 设置信号处理（必须在脚本开头设置才能捕获所有信号）
trap '_download_cancelled="true"' INT TERM

# 命令行参数解析
parse_arguments() {
    local target_menu=""
    local target_function=""
    local goto_menu=""
    local server_name=""
    local jdk_version=""
    local skip_welcome=false
    local skip_main_menu=false
    local debug_mode=false
    local no_gui=false
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            -t|--target-menu)
                target_menu="$2"
                skip_main_menu=true
                no_gui=true
                shift 2
                ;;
            -tf|--target-function)
                target_function="$2"
                skip_main_menu=true
                no_gui=true
                shift 2
                ;;
            -gof|--goto-menu)
                goto_menu="$2"
                skip_main_menu=false  # 不跳过主菜单
                # 不设置 no_gui，让脚本根据环境决定使用 GUI 还是 CLI
                shift 2
                ;;
            -n|--name)
                server_name="$2"
                shift 2
                ;;
            -j|--jdk)
                jdk_version="$2"
                shift 2
                ;;
            -v|--version)
                echo "Minecraft Server Manager v$MANAGER_VERSION"
                exit 0
                ;;
            -d|--debug)
                debug_mode=true
                shift
                ;;
            --skip-welcome)
                skip_welcome=true
                shift
                ;;
            --no-gui)
                no_gui=true
                shift
                ;;
            -h|--help)
                show_help
                exit 0
                ;;
            --list-menus)
                NO_GUI=true
                list_available_menus
                exit 0
                ;;
            --list-functions)
                NO_GUI=true
                list_available_functions
                exit 0
                ;;
            --list-servers)
                NO_GUI=true
                list_servers
                exit 0
                ;;
            --list-jdks)
                NO_GUI=true
                list_jdks
                exit 0
                ;;
            --status)
                NO_GUI=true
                show_system_status
                exit 0
                ;;
            --start-server)
                if [ -n "$2" ]; then
                    start_server_direct "$2"
                else
                    echo "错误: 需要指定服务器名称"
                    exit 1
                fi
                exit 0
                ;;
            --update-manager)
                update_manager_direct
                exit 0
                ;;
            --install-jdk)
                if [ -n "$2" ]; then
                    install_jdk_direct "$2"
                else
                    echo "错误: 需要指定JDK版本"
                    exit 1
                fi
                exit 0
                ;;
            --backup-server)
                NO_GUI=true
                if [ -n "$2" ]; then
                    backup_server_direct "$2"
                else
                    echo "错误: 需要指定服务器名称"
                    exit 1
                fi
                exit 0
                ;;
            *)
                echo "未知参数: $1"
                show_help
                exit 1
                ;;
        esac
    done
    
    # 设置全局变量
    TARGET_MENU="$target_menu"
    TARGET_FUNCTION="$target_function"
    GOTO_MENU="$goto_menu"  # 新增：存储跳转菜单
    SERVER_NAME="$server_name"
    JDK_VERSION="$jdk_version"
    SKIP_WELCOME="$skip_welcome"
    SKIP_MAIN_MENU="$skip_main_menu"
    DEBUG_MODE="$debug_mode"
    NO_GUI="$no_gui"
}

# 显示帮助信息
show_help() {
    cat << EOF
Minecraft Java 服务器管理器 - 使用说明

用法: $0 [选项]

选项:
  -t, --target-menu MENU_NAME     直接跳转到指定菜单
  -tf, --target-function FUNC_NAME 直接执行指定函数
  -gof, --goto-menu MENU_NAME     跳转到指定菜单但可返回主菜单
  -n, --name SERVER_NAME          指定服务器名称
  -j, --jdk JDK_VERSION           指定JDK版本
  -v, --version                   显示版本信息
  -d, --debug                     启用调试模式
  --skip-welcome                  跳过欢迎界面
  --no-gui                        不使用图形界面
  -h, --help                      显示此帮助信息
  
高级选项:
  --list-menus                    列出所有可用菜单
  --list-functions                列出所有可用函数
  --list-servers                  列出所有服务器
  --list-jdks                     列出所有JDK
  --status                        显示系统状态
  --start-server SERVER_NAME      直接启动服务器
  --backup-server SERVER_NAME     直接备份服务器
  --update-manager                直接更新管理器
  --install-jdk JDK_VERSION       直接安装JDK

示例:
  $0 -t "server_management"                 # 直接进入服务器管理菜单
  $0 -tf "manage_existing_servers" -n "ss" # 管理特定服务器
  $0 --start-server "my_server"            # 直接启动服务器
  $0 --list-servers                        # 列出所有服务器
  $0 --goto-menu "server_management"       # 跳转到服务器管理菜单，可返回
EOF
}

# 列出所有可用菜单
list_available_menus() {
    cat << EOF
可用菜单:
  main_menu              - 主菜单
  server_management      - 服务器管理
  jdk_management         - JDK管理
  hp_management          - 内网穿透管理
  system_settings        - 系统设置
EOF
}

# 列出所有可用函数
list_available_functions() {
    cat << EOF
可用函数:
服务器管理:
  create_server                 - 创建新服务器
  manage_existing_servers       - 管理现有服务器
  start_server                 - 启动服务器
  cli_configure_server         - 配置服务器
  manage_server_files          - 文件与配置
  backup_server                - 备份服务器
  delete_server                - 删除服务器

JDK管理:
  install_jdk                  - 安装JDK
  manage_installed_jdks        - 管理已安装JDK
  auto_configure_jdk           - 自动配置JDK

内网穿透:
  download_hp_client           - 下载HPPRO客户端
  set_device_id                - 设置设备ID
  start_hp_service             - 启动HPPRO服务
  stop_hp_service              - 停止HPPRO服务

系统设置:
  update_manager               - 更新管理器
EOF
}

# 列出所有服务器
list_servers() {
    if [ ! -f "$CONFIG_FILE" ]; then
        echo "没有找到配置文件"
        return
    fi
    
    echo "已配置的服务器:"
    jq -r '.servers[] | "\(.name) - \(.type) \(.version)"' "$CONFIG_FILE" 2>/dev/null || echo "没有配置服务器"
}

# 列出所有JDK
list_jdks() {
    if [ ! -f "$CONFIG_FILE" ]; then
        echo "没有找到配置文件"
        return
    fi
    
    echo "已安装的JDK:"
    jq -r '.jdks[] | "\(.name) - \(.provider)"' "$CONFIG_FILE" 2>/dev/null || echo "没有安装JDK"
}

# 显示系统状态
show_system_status() {
    echo "=== Minecraft Java 服务器管理器状态 ==="
    echo "版本: $MANAGER_VERSION"
    echo "系统架构: $ARCH"
    echo "发行版: $DISTRO"
    echo ""
    
    # 服务器状态
    echo "服务器状态:"
    if [ -f "$CONFIG_FILE" ]; then
        while IFS= read -r server; do
            local name=$(echo "$server" | jq -r '.name')
            local status="已停止"
            if is_server_running "$name"; then
                status="运行中"
            fi
            echo "  $name - $status"
        done < <(jq -c '.servers[]' "$CONFIG_FILE" 2>/dev/null)
    else
        echo "  没有配置服务器"
    fi
    
    echo ""
    
    # HPPRO状态
    echo "内网穿透状态:"
    if is_hp_running; then
        echo "  HPPRO: 运行中"
    else
        echo "  HPPRO: 未运行"
    fi
}

# Whiptail 终端UI封装

safe_whiptail() {
    # 保存终端设置
    local original_stty=$(stty -g 2>/dev/null)
    local original_lang="$LANG"
    local original_lc_all="$LC_ALL"
    
    # 设置安全的编码环境
    export LANG="C.UTF-8"
    export LC_ALL="C.UTF-8"
    
    # 执行whiptail命令
    whiptail "$@"
    local result=$?
    
    # 立即恢复终端设置
    if [ -n "$original_stty" ]; then
        stty "$original_stty" 2>/dev/null
    fi
    stty sane 2>/dev/null
    
    # 恢复语言环境
    export LANG="$original_lang"
    export LC_ALL="$original_lc_all"
    
    return $result
}

# ============================================
# UI 抽象层函数（支持 GUI/CLI 模式）
# ============================================

# 文本输入（GUI: inputbox / CLI: read）
ui_input() {
    local prompt="$1"
    local default="${2:-}"

    if [ "$NO_GUI" = "true" ]; then
        # CLI 模式 - 提示符输出到 stderr，避免混入返回值
        if [ -n "$default" ]; then
            printf "%s [默认: %s]: " "$prompt" "$default" >&2
        else
            printf "%s: " "$prompt" >&2
        fi
        read -r input
        # 返回值
        echo "${input:-$default}"
    else
        # GUI 模式
        safe_whiptail --inputbox "$prompt" 10 50 "${default:-}" 3>&1 1>&2 2>&3
    fi
}

# 菜单选择（GUI: menu / CLI: 编号选择）
ui_select() {
    local title="$1"
    shift
    local options=("$@")
    local option_count=${#options[@]}

    if [ "$NO_GUI" = "true" ]; then
        # CLI 模式 - 菜单输出到 stderr，返回值输出到 stdout
        echo "" >&2
        echo "=== ${title} ===" >&2
        echo "" >&2
        for i in "${!options[@]}"; do
            local idx=$((i + 1))
            local opt="${options[$i]}"
            # 解析 "值: 描述" 格式
            local key="${opt%%:*}"
            local desc="${opt#*:}"
            if [ "$key" = "$desc" ]; then
                echo "  ${idx}) ${opt}" >&2
            else
                echo "  ${idx}) ${desc}" >&2
            fi
        done
        echo "" >&2
        echo -n "请选择 [1-${option_count}]: " >&2
        read -r choice

        # 验证输入
        if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$option_count" ]; then
            local idx=$((choice - 1))
            local opt="${options[$idx]}"
            echo "${opt%%:*}"
        else
            echo ""
            return 1
        fi
    else
        # GUI 模式
        safe_whiptail --title "$title" --menu "请选择：" 15 50 10 "${options[@]}" 3>&1 1>&2 2>&3
    fi
}

# 确认/否定（GUI: yesno / CLI: y/n）
ui_confirm() {
    local prompt="$1"

    if [ "$NO_GUI" = "true" ]; then
        # CLI 模式
        echo -ne "${prompt} [y/N]: "
        read -r choice
        case "$choice" in
            [yY]|[yY][eE][sS])
                return 0
                ;;
            *)
                return 1
                ;;
        esac
    else
        # GUI 模式
        safe_whiptail --title "确认" --yesno "$prompt" 10 60
    fi
}

# Yes/No 选择（返回 0=是, 1=否）
ui_yesno() {
    local prompt="$1"

    if [ "$NO_GUI" = "true" ]; then
        # CLI 模式
        echo -ne "${prompt} [y/N]: "
        read -r choice
        case "$choice" in
            [yY]|[yY][eE][sS])
                return 0
                ;;
            *)
                return 1
                ;;
        esac
    else
        # GUI 模式
        safe_whiptail --title "确认" --yesno "$prompt" 10 60
    fi
}

# 消息输出（GUI: msgbox / CLI: echo）
ui_message() {
    local title="$1"
    local msg="$2"

    if [ "$NO_GUI" = "true" ]; then
        # CLI 模式
        echo ""
        echo "=== ${title} ==="
        echo ""
        echo -e "$msg"
        echo ""
    else
        # GUI 模式
        safe_whiptail --title "$title" --msgbox "$msg" 10 50
    fi
}

# 显示信息（仅输出，不等待确认）
ui_info() {
    local msg="$1"

    if [ "$NO_GUI" = "true" ]; then
        echo -e "$msg"
    else
        safe_whiptail --title "信息" --msgbox "$msg" 10 50
    fi
}

# 显示警告
ui_warn() {
    local msg="$1"

    if [ "$NO_GUI" = "true" ]; then
        echo -e "${YELLOW}警告: ${msg}${NC}"
    else
        safe_whiptail --title "警告" --msgbox "$msg" 10 50
    fi
}

# 显示错误
ui_error() {
    local msg="$1"

    if [ "$NO_GUI" = "true" ]; then
        echo -e "${RED}错误: ${msg}${NC}" >&2
    else
        safe_whiptail --title "错误" --msgbox "$msg" 10 50
    fi
}

# 显示进度条（CLI: 简单实现 / GUI: 可用 whiptail gauge）
ui_progress() {
    local percent="$1"
    local message="$2"

    if [ "$NO_GUI" = "true" ]; then
        # CLI 模式简单进度显示
        printf "\r[%s] %s" "$(printf '#%.0s' $(seq 1 $((percent / 5))) 2>/dev/null)$(printf '.%.0s' $(seq 1 $((20 - percent / 5))) 2>/dev/null)" "$message"
        if [ "$percent" -ge 100 ]; then
            echo ""
        fi
    else
        # GUI 模式 - whiptail 不支持动态进度条，使用简单消息
        echo "$message ($percent%)"
    fi
}

# 分页显示内容（CLI: less/cat / GUI: textbox）
ui_pager() {
    local title="$1"
    local content="$2"

    if [ "$NO_GUI" = "true" ]; then
        # CLI 模式
        {
            echo "=== ${title} ==="
            echo ""
            echo "$content"
        } | less -R
    else
        # 写入临时文件供 GUI 显示
        local tmp_file="/tmp/mc_manager_${RANDOM}.txt"
        echo "$content" > "$tmp_file"
        safe_whiptail --title "$title" --textbox "$tmp_file" 25 80
        rm -f "$tmp_file"
    fi
}

# CLI 通用菜单选择（处理数组格式的选项）
cli_menu_select() {
    local title="$1"
    shift
    local options=("$@")
    local option_count=${#options[@]}

    echo ""
    echo "=== ${title} ==="
    echo ""
    for i in "${!options[@]}"; do
        local idx=$((i + 1))
        local opt="${options[$i]}"
        # 解析 "值: 描述" 格式
        local key="${opt%%:*}"
        local desc="${opt#*:}"
        if [ "$key" = "$desc" ]; then
            echo "  ${idx}) ${opt}"
        else
            echo "  ${idx}) ${desc}"
        fi
    done
    echo ""
    echo -n "请选择 [1-${option_count}]: "
    read -r choice

    # 验证输入
    if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$option_count" ]; then
        local idx=$((choice - 1))
        local opt="${options[$idx]}"
        echo "${opt%%:*}"
    else
        echo ""
        return 1
    fi
}

# CLI 简单 yes/no 选择
cli_yes_no() {
    local prompt="$1"
    echo -ne "${prompt} [y/N]: "
    read -r choice
    case "$choice" in
        [yY]|[yY][eE][sS])
            return 0
            ;;
        *)
            return 1
            ;;
    esac
}

# 直接执行功能（无GUI）

# 直接启动服务器
start_server_direct() {
    local server_name="$1"
    
    if ! is_server_exists "$server_name"; then
        echo "错误: 服务器 '$server_name' 不存在"
        return 1
    fi
    
    if is_server_running "$server_name"; then
        echo "服务器 '$server_name' 已经在运行中"
        return 0
    fi
    
    echo "正在启动服务器 '$server_name'..."
    start_server "$server_name"
}

# 直接备份服务器
backup_server_direct() {
    local server_name="$1"

    if ! is_server_exists "$server_name"; then
        echo "错误: 服务器 '$server_name' 不存在"
        return 1
    fi

    echo "正在备份服务器 '$server_name'..."
    if backup_server "$server_name"; then
        echo "服务器 '$server_name' 备份完成"
        return 0
    else
        echo "服务器 '$server_name' 备份失败"
        return 1
    fi
}

# 直接安装JDK
install_jdk_direct() {
    local jdk_version="$1"
    
    echo "正在安装 JDK $jdk_version..."
    if install_jdk_version "$jdk_version"; then
        echo "JDK $jdk_version 安装成功"
    else
        echo "JDK $jdk_version 安装失败"
        return 1
    fi
}

# 获取脚本绝对路径

# 获取脚本的绝对路径
get_script_path() {
    local SOURCE="${BASH_SOURCE[0]}"
    while [ -h "$SOURCE" ]; do
        local DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
        SOURCE="$(readlink "$SOURCE")"
        [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
    done
    echo "$( cd -P "$( dirname "$SOURCE" )" && pwd )/$(basename "$SOURCE")"
}

SCRIPT_PATH=$(get_script_path)
SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"

# 变量配置

# 全局颜色配置 (使用 $'' 语法支持转义序列)
RED=$'\033[0;31m'
GREEN=$'\033[0;32m'
YELLOW=$'\033[1;33m'
BLUE=$'\033[0;34m'
CYAN=$'\033[0;36m'
MAGENTA=$'\033[0;35m'
WHITE=$'\033[1;37m'
GRAY=$'\033[0;90m'  # 亮灰色 (用于进度条未完成部分)
NC=$'\033[0m' # 无颜色

# 路径配置 - 使用脚本所在目录下的 MCManager/
BASE_DIR="$SCRIPT_DIR/MCManager"
MCSERVER_DIR="$BASE_DIR/servers"
MCJDK_DIR="$BASE_DIR/jdk"
CONFIG_DIR="$BASE_DIR/config"
PLUGIN_DIR="$CONFIG_DIR/plugins"
MOD_DIR="$CONFIG_DIR/mods"
LOG_DIR="$BASE_DIR/logs"
HP_DIR="$CONFIG_DIR/hppro"
HP_LOG_FILE="$LOG_DIR/hp-client.log"

# 配置文件
CONFIG_FILE="$CONFIG_DIR/config.json"

# 默认供应商
DEFAULT_PROVIDER="adoptium"

# JDK 供应商信息定义
declare -A JDK_PROVIDERS=(
    [adoptium]="Eclipse Temurin"
    [liberica]="BellSoft Liberica"
    [corretto]="Amazon Corretto"
    [zulu]="Azul Zulu"
    [openjdk]="OpenJDK (官方)"
)

declare -A PROVIDER_DESCRIPTIONS=(
    [adoptium]="Eclipse Foundation 维护的 OpenJDK 构建，推荐使用"
    [liberica]="BellSoft 提供，支持 JavaFX，带有小型运行时"
    [corretto]="Amazon 提供，长期支持，免费使用"
    [zulu]="Azul Systems 提供，社区版免费，企业版付费"
    [openjdk]="Oracle 官方开源版本，无商业支持"
)

declare -A PROVIDER_VERSIONS=(
    [adoptium]="8,11,17,21,22"
    [liberica]="8-21"
    [corretto]="8,11,17,21"
    [zulu]="8-21"
    [openjdk]="8,11,17,21"
)

declare -A PROVIDER_FEATURES=(
    [adoptium]="免费|LTS|推荐"
    [liberica]="免费|JavaFX|小型运行时"
    [corretto]="免费|LTS|Amazon支持"
    [zulu]="社区免费|企业付费"
    [openjdk]="免费|官方"
)

declare -A PROVIDER_URLS=(
    [adoptium]="https://adoptium.net"
    [liberica]="https://bell-sw.com"
    [corretto]="https://aws.amazon.com/corretto"
    [zulu]="https://www.azul.com"
    [openjdk]="https://openjdk.org"
)

# 初始化配置文件
init_config() {
    if [ ! -f "$CONFIG_FILE" ]; then
        cat > "$CONFIG_FILE" << EOF
{
    "manager": {
        "version": "$MANAGER_VERSION",
        "default_java_version": "暂未设置"
    },
    "servers": [],
    "jdks": [],
    "hppro": {
        "device_id": "",
        "downloaded": false
    },
    "system": {
        "last_update_check": "",
        "backup_path": ""
    },
    "providers": {
        "default": "adoptium",
        "enabled": {
            "adoptium": true,
            "liberica": true,
            "corretto": true,
            "zulu": true,
            "openjdk": true
        }
    }
}
EOF
    fi
}

# 加载配置
load_config() {
    if [ -f "$CONFIG_FILE" ]; then
        HP_DEVICE_ID=$(jq -r '.hppro.device_id' "$CONFIG_FILE")
        HP_DOWNLOADED=$(jq -r '.hppro.downloaded' "$CONFIG_FILE")
        # 加载默认供应商
        DEFAULT_PROVIDER=$(jq -r '.providers.default // "adoptium"' "$CONFIG_FILE")
    else
        HP_DEVICE_ID=""
        HP_DOWNLOADED="false"
        DEFAULT_PROVIDER="adoptium"
    fi
}

# 保存配置
save_config() {
    local temp_file="$CONFIG_FILE.tmp"

    jq --arg device_id "$HP_DEVICE_ID" \
       --argjson downloaded "$HP_DOWNLOADED" \
       '.hppro.device_id = $device_id |
        .hppro.downloaded = $downloaded' "$CONFIG_FILE" > "$temp_file" && mv "$temp_file" "$CONFIG_FILE"
}

# 保存服务器列表
save_servers_config() {
    local temp_file="$CONFIG_FILE.tmp"
    local servers_json="[]"
    
    if [ -f "$CONFIG_FILE" ]; then
        while IFS= read -r server; do
            local name=$(echo "$server" | jq -r '.name')
            local type=$(echo "$server" | jq -r '.type')
            local version=$(echo "$server" | jq -r '.version')
            servers_json=$(echo "$servers_json" | jq --arg name "$name" --arg type "$type" --arg version "$version" '. += [{"name": $name, "type": $type, "version": $version}]')
        done < <(jq -c '.servers[]' "$CONFIG_FILE")
    fi
    
    jq --argjson servers "$servers_json" '.servers = $servers' "$CONFIG_FILE" > "$temp_file" && mv "$temp_file" "$CONFIG_FILE"
}

# 保存JDK列表
save_jdks_config() {
    local temp_file="$CONFIG_FILE.tmp"
    local jdks_json="[]"
    
    if [ -f "$CONFIG_FILE" ]; then
        while IFS= read -r jdk; do
            local name=$(echo "$jdk" | jq -r '.name')
            local provider=$(echo "$jdk" | jq -r '.provider')
            jdks_json=$(echo "$jdks_json" | jq --arg name "$name" --arg provider "$provider" '. += [{"name": $name, "provider": $provider}]')
        done < <(jq -c '.jdks[]' "$CONFIG_FILE")
    fi
    
    jq --argjson jdks "$jdks_json" '.jdks = $jdks' "$CONFIG_FILE" > "$temp_file" && mv "$temp_file" "$CONFIG_FILE"
}

# 系统检测

# 检测系统架构
ARCH=$(uname -m)
case $ARCH in
    x86_64) ARCH="amd64" ;;
    aarch64) ARCH="arm64" ;;
    *) ARCH="unknown" ;;
esac

# 检测发行版
if [ -f /etc/os-release ]; then
    . /etc/os-release
    DISTRO=$ID
else
    DISTRO="unknown"
fi

# 依赖检查与环境检测

# 检查系统依赖
check_dependencies() {
    # 定义依赖映射：包名 -> 命令名
    local -A dep_mapping=(
        ["vim"]="vim"
        ["vi"]="vi"
        ["curl"]="curl"
        ["wget"]="wget"
        ["jq"]="jq"
        ["unzip"]="unzip"
        ["tar"]="tar"
        ["whiptail"]="whiptail"
        ["bc"]="bc"
        ["file"]="file"
    )
    
    local missing_packages=()
    local missing_commands=()
    local has_errors=false
    
    # 检查每个命令是否存在
    for package_name in "${!dep_mapping[@]}"; do
        local command_name="${dep_mapping[$package_name]}"
        
        if ! command -v "$command_name" &> /dev/null; then
            missing_packages+=("$package_name")
            missing_commands+=("$command_name")
            has_errors=true
        fi
    done
    
    # 如果没有缺失的依赖，静默返回
    if [ ${#missing_packages[@]} -eq 0 ]; then
        return 0
    fi
    
    # 只在有缺失依赖时显示信息
    echo -e "${YELLOW}缺失依赖: ${missing_packages[*]}${NC}"
    echo -e "${BLUE}尝试自动安装...${NC}"
    

    case $DISTRO in
        ubuntu|debian)
            sudo apt update >/dev/null 2>&1
            sudo apt install -y "${missing_packages[@]}" >/dev/null 2>&1
            ;;
        fedora)
            sudo dnf install -y "${missing_packages[@]}" >/dev/null 2>&1
            ;;
        centos|rhel)
            sudo yum install -y "${missing_packages[@]}" >/dev/null 2>&1
            ;;
        arch)
            sudo pacman -Sy --noconfirm "${missing_packages[@]}" >/dev/null 2>&1
            ;;
        *)
            echo -e "${RED}无法自动安装依赖${NC}"
            echo -e "${YELLOW}请手动安装: ${missing_packages[*]}${NC}"
            return 1
            ;;
    esac
    
    # 验证安装结果
    local success=true
    
    for cmd in "${missing_commands[@]}"; do
        if ! command -v "$cmd" &> /dev/null; then
            echo -e "${RED}✗✗ $cmd 安装失败${NC}"
            success=false
            has_errors=true
        fi
    done
    
    if [ "$success" = true ]; then
        echo -e "${GREEN}依赖安装完成${NC}"
        return 0
    else
        echo -e "${YELLOW}部分依赖安装失败，但脚本可以继续运行${NC}"
        return 1
    fi
}

# 检查 whiptail 是否可用（GUI 模式必需）
check_whiptail() {
    # 检查 whiptail 命令是否存在
    if ! command -v whiptail &> /dev/null; then
        echo -e "${RED}错误: whiptail 未安装${NC}"
        echo ""
        echo -e "${YELLOW}GUI 模式需要 whiptail，请选择以下方案之一:${NC}"
        echo "  1. 安装 whiptail 后重新运行脚本"
        echo "  2. 使用 --no-gui 参数进入 CLI 模式"
        echo ""
        echo "安装 whiptail:"
        echo "  - Ubuntu/Debian: sudo apt install whiptail"
        echo "  - Fedora: sudo dnf install newt"
        echo "  - CentOS/RHEL: sudo yum install newt"
        echo ""
        echo -e "${BLUE}或者直接运行: $0 --no-gui${NC}"
        exit 1
    fi

    # 测试 whiptail 是否能在当前终端运行
    # 使用简单的 --version 测试，如果失败说明终端不支持
    if ! timeout 3 whiptail --version &> /dev/null 2>&1; then
        echo -e "${RED}错误: whiptail 无法在此终端运行${NC}"
        echo ""
        echo -e "${YELLOW}可能原因: 终端不支持图形界面或环境配置问题${NC}"
        echo ""
        echo -e "${BLUE}建议使用 --no-gui 参数进入 CLI 模式:${NC}"
        echo "  $0 --no-gui"
        exit 1
    fi
}

# 验证安装结果
verify_installation() {
    local commands=("$@")
    local success=true
    
    echo -e "${BLUE}验证安装结果...${NC}"
    
    for cmd in "${commands[@]}"; do
        if command -v "$cmd" &> /dev/null; then
            echo -e "${GREEN}✓ $cmd 安装成功${NC}"
        else
            echo -e "${RED}✗✗ $cmd 安装失败${NC}"
            success=false
        fi
    done
    
    if [ "$success" = true ]; then
        echo -e "${GREEN}依赖安装完成${NC}"
        return 0
    else
        echo -e "${YELLOW}部分依赖安装失败，但脚本可以继续运行${NC}"
        return 1
    fi
}

# 检查编辑器可用性
check_editors_availability() {
    local editors_available=()
    
    if command -v vim &> /dev/null; then
        editors_available+=("vim")
    fi
    
    if command -v vi &> /dev/null; then
        editors_available+=("vi")
    fi
    
    # 如果没有找到任何编辑器，才显示警告
    if [ ${#editors_available[@]} -eq 0 ]; then
        echo -e "${YELLOW}警告: 没有找到可用的文本编辑器${NC}"
        echo -e "${BLUE}建议安装一个编辑器以获得更好的文件编辑体验${NC}"
        
        echo -e "${GREEN}推荐安装: vim${NC}"
    fi
}

# 增强的编辑器检测函数
detect_best_editor() {
    # 按优先级检测可用的编辑器
    if command -v vim &> /dev/null; then
        echo "vim"
        return 0
    elif command -v vi &> /dev/null; then
        echo "vi"
        return 0
    else
        echo ""
        return 1
    fi
}

# 获取编辑器命令
get_editor_command() {
    local file_path="$1"
    local editor=$(detect_best_editor)
    
    case "$editor" in
        "vim")
            echo "vim '+set number' '+syntax on' '$file_path'"
            ;;
        "vi")
            echo "vi '+set number' '$file_path' 2>/dev/null || vi '$file_path'"
            ;;
        *)
            echo ""
            return 1
            ;;
    esac
}

# 主菜单与程序入口

# 显示欢迎信息
show_welcome() {
    safe_whiptail --clear \
        --title "Minecraft Java 服务器管理器" \
        --msgbox "\n欢迎使用 Minecraft Java 服务器管理器\n\n版本: $MANAGER_VERSION" 12 50
}

# 主菜单
main_menu() {
    while true; do
        # 获取当前状态信息
        local status_msg=$(show_status_info)

        # 显示主菜单
        choice=$(safe_whiptail --nocancel --clear \
            --title "Minecraft Java 服务器管理器" \
            --menu "$status_msg" 18 50 6 \
            "1" "服务器管理" \
            "2" "JDK 管理" \
            "3" "内网穿透设置" \
            "4" "系统设置" \
            "0" "退出" \
            3>&1 1>&2 2>&3)

        [ $? -ne 0 ] && exit 0

        case $choice in
            1) server_management ;;
            2) jdk_management ;;
            3) hp_management ;;
            4) system_settings ;;
            0 | "") exit 0 ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# ============================================
# CLI 模式主菜单（无GUI模式）
# ============================================

# 显示 CLI 欢迎信息
cli_show_welcome() {
    echo ""
    echo "=========================================="
    echo "   Minecraft Java 服务器管理器"
    echo "   版本: $MANAGER_VERSION"
    echo "   模式: 命令行交互模式"
    echo "=========================================="
    echo ""
}

# CLI 主菜单
cli_main_menu() {
    while true; do
        # 清屏并显示欢迎信息
        clear 2>/dev/null || printf "\033[2J\033[H"
        cli_show_welcome

        # 显示状态信息
        local status_info
        status_info=$(show_status_info 2>/dev/null || echo "系统正常")
        echo "$status_info"
        echo ""

        # 显示菜单选项
        echo "============================================"
        echo "           主菜单"
        echo "============================================"
        echo ""
        echo "  1) 服务器管理     - 创建、启动、配置服务器"
        echo "  2) JDK 管理      - 安装、切换 JDK 版本"
        echo "  3) 内网穿透设置  - 配置 HPPRO 穿透服务"
        echo "  4) 系统设置      - 更新、检查、清理"
        echo "  0) 退出          - 退出程序"
        echo ""
        echo "--------------------------------------------"

        echo -n "请输入选项编号 [0-4]: "
        read -r choice

        # 处理空输入
        if [ -z "$choice" ]; then
            echo ""
            continue
        fi

        case "$choice" in
            1)
                echo ""
                echo ">>> 进入服务器管理..."
                echo ""
                cli_server_management
                ;;
            2)
                echo ""
                echo ">>> 进入 JDK 管理..."
                echo ""
                cli_jdk_management
                ;;
            3)
                echo ""
                echo ">>> 进入内网穿透设置..."
                echo ""
                cli_hp_management
                ;;
            4)
                echo ""
                echo ">>> 进入系统设置..."
                echo ""
                cli_system_settings
                ;;
            0 | "")
                echo ""
                echo "感谢使用，再见！"
                echo ""
                return 0
                ;;
            *)
                echo ""
                echo -e "${RED}无效选项 '$choice'，请重新输入${NC}"
                echo ""
                echo ""
                ;;
        esac
    done
}

# 初始化检查
init_checks() {
    # 检查依赖（包括 jq）
    if ! check_dependencies; then
        # 检查 jq 是否存在（JDK 下载必需）
        if ! command -v jq &> /dev/null; then
            echo -e "${RED}错误: jq 是必需的依赖，用于解析 JDK API 响应${NC}"
            echo -e "${YELLOW}请先安装 jq:${NC}"
            echo "  Ubuntu/Debian: sudo apt install jq"
            echo "  Fedora: sudo dnf install jq"
            echo "  CentOS: sudo yum install jq"
            exit 1
        fi
    fi
    
    # 检查目录
    mkdir -p "$MCSERVER_DIR" "$MCJDK_DIR" "$CONFIG_DIR" "$PLUGIN_DIR" "$MOD_DIR" "$LOG_DIR" "$HP_DIR"
    
    # 初始化配置文件
    if [ ! -f "$CONFIG_FILE" ]; then
        init_config
    fi
    
    # 初始化HPPRO配置
    init_hp_config
    
    # 初始化日志
    init_log
    
    # 加载配置
    load_config
}

# 错误处理与清理

# 清理退出
cleanup_on_exit() {
    # 使用全局变量存储的退出码，而不是 $?
    local exit_code=${CLI_EXIT_CODE:-0}

    # 如果是编辑模式或日志查看模式，特殊处理
    if [ "$IN_EDIT_MODE" = "true" ] || [ "$IN_LOG_VIEW_MODE" = "true" ]; then
        restore_terminal_settings
        export IN_EDIT_MODE="false"
        export IN_LOG_VIEW_MODE="false"
        
        # 返回适当的菜单
        if [ -n "$CURRENT_SERVER" ]; then
            exec "$SCRIPT_PATH" --skip-welcome --goto-menu "server_management" -n "$CURRENT_SERVER"
        else
            exec "$SCRIPT_PATH" --skip-welcome
        fi
    fi
    
    # 记录退出信息
    if [ $exit_code -ne 0 ]; then
        echo -e "${RED}非正常退出，退出代码: $exit_code${NC}"
        mkdir -p "$LOG_DIR"
        echo "[$(date)] 非正常退出，退出代码: $exit_code" >> "$LOG_DIR/error.log"
    fi
    
    # 关闭内网穿透
    if is_hp_running; then
        echo -e "${YELLOW}检测到内网穿透正在运行，正在关闭...${NC}"
        stop_hp_service
    fi
    
    # 恢复终端设置
    stty "$original_term" 2>/dev/null || true
    
    # 清理临时文件
    rm -f "$CONFIG_FILE.tmp" 2>/dev/null
    rm -f "$MCSERVER_DIR"/*.tmp 2>/dev/null
    
    # 如果是调试模式，显示调试信息
    if [ "$DEBUG_MODE" = "true" ]; then
        echo -e "${YELLOW}调试模式已启用${NC}"
        set +x
    fi
}

# 错误处理
error_handler() {
    local exit_code=$?
    local error_line=$1
    
    # 如果是编辑文件时的Ctrl+C，特殊处理
    if [ "$IN_EDIT_MODE" = "true" ]; then
        echo -e "\n${YELLOW}编辑已取消${NC}"
        restore_terminal_settings
        export IN_EDIT_MODE="false"
        # 返回文件与配置菜单
        if [ -n "$CURRENT_SERVER" ]; then
            exec "$SCRIPT_PATH" --skip-welcome --goto-menu "server_management" -n "$CURRENT_SERVER"
        else
            exec "$SCRIPT_PATH" --skip-welcome
        fi
    fi
    
    # 如果是日志查看时的错误，尝试恢复
    if [ "$IN_LOG_VIEW_MODE" = "true" ]; then
        echo -e "\n${RED}日志查看过程中发生错误${NC}"
        restore_terminal_settings
        export IN_LOG_VIEW_MODE="false"
        # 尝试返回适当的菜单
        if [ -n "$CURRENT_SERVER" ]; then
            exec "$SCRIPT_PATH" --skip-welcome --goto-menu "server_management" -n "$CURRENT_SERVER"
        else
            exec "$SCRIPT_PATH" --skip-welcome
        fi
    fi
    
    # 记录错误日志
    mkdir -p "$LOG_DIR"
    echo "[$(date)] 错误发生在第 $error_line 行: $BASH_COMMAND (退出代码: $exit_code)" >> "$LOG_DIR/error.log"
    
    # 对于Ctrl+C，直接返回菜单
    if [ $exit_code -eq 130 ]; then # 130是Ctrl+C的退出码
        if [ "$NO_GUI" = "true" ]; then
            echo -e "\n${YELLOW}操作已取消${NC}"
            exit 0
        else
            # GUI模式显示信息并返回
            echo -e "\n${YELLOW}操作已取消，返回菜单...${NC}"
            sleep 1
            # 重新启动管理器返回菜单
            exec "$SCRIPT_PATH" --skip-welcome
        fi
    fi
    
    # 其他错误
    if [ "$NO_GUI" = "true" ]; then
        echo "错误发生在第 $error_line 行: $BASH_COMMAND"
        echo "退出代码: $exit_code"
    else
        # GUI模式显示错误
        clear
        echo -e "${RED}发生错误!${NC}"
        echo -e "行号: $error_line"
        echo -e "命令: $BASH_COMMAND"
        echo -e "退出代码: $exit_code"
        echo -e "${YELLOW}正在恢复界面...${NC}"
        sleep 3
        
        # 尝试恢复图形界面
        exec "$SCRIPT_PATH" --skip-welcome
    fi
}

# 工具类函数

# 显示状态信息
show_status_info() {
    local status_info=""
    
    # 获取服务器运行状态
    local running_servers=()
    if [ -f "$CONFIG_FILE" ]; then
        while IFS= read -r server; do
            local name=$(echo "$server" | jq -r '.name')
            if is_server_running "$name"; then
                running_servers+=("$name")
            fi
        done < <(jq -c '.servers[]' "$CONFIG_FILE")
    fi
    
    # 获取HPPRO状态
    local hp_status="未运行"
    if is_hp_running; then
        hp_status="运行中"
        if [ -f "$HP_DIR/hp-client.pid" ]; then
            local pid=$(cat "$HP_DIR/hp-client.pid")
            hp_status+=" (PID: $pid)"
        fi
    fi
    
    # 构建状态信息
    status_info+="服务器状态: "
    if [ ${#running_servers[@]} -eq 0 ]; then
        status_info+="无服务器运行\n"
    else
        status_info+="运行中: ${running_servers[*]}\n"
    fi
    
    status_info+="内网穿透: $hp_status\n"

    echo -e "$status_info"
}

# 初始化日志
init_log() {
    mkdir -p "$LOG_DIR"
    local log_file="$LOG_DIR/manager_$(date +%Y%m%d).log"
    exec 3>&1 4>&2
    exec > >(tee -a "$log_file") 2>&1
}

# 显示消息框
show_msg() {
    local title="$1"
    local msg="$2"
    ui_message "$title" "$msg"
}

# 获取终端宽度
get_progress_bar_width() {
    local term_width

    # 方法1: 使用tput
    if command -v tput >/dev/null 2>&1; then
        term_width=$(tput cols 2>/dev/null)
    fi

    # 使用stty
    if [ -z "$term_width" ] && command -v stty >/dev/null 2>&1; then
        term_width=$(stty size 2>/dev/null | awk '{print $2}')
    fi

    # 使用环境变量
    if [ -z "$term_width" ] && [ -n "$COLUMNS" ]; then
        term_width=$COLUMNS
    fi

    # 使用默认值
    if [ -z "$term_width" ]; then
        term_width=80
    fi

    # 计算进度条宽度（终端宽度减去进度百分比、速度等信息的宽度）
    # 显示格式: [===============>] 100% | XX.X MB/s ✓
    # 大约占用的固定字符: [ ] + 100% + | + 速度 + ✓  ≈ 25字符
    local bar_width=$((term_width - 25))

    # 设置最小宽度限制
    if [ $bar_width -lt 15 ]; then
        bar_width=15
    fi

    echo $bar_width
}

#显示进度条（单行模式，用于兼容性）
show_progress() {
    local title="$1"
    local msg="$2"
    local percent="$3"
    local bar_width="$4"
    local speed="$5"

    local filled_width=$((percent * bar_width / 100))
    local empty_width=$((bar_width - filled_width))

    local bar="["
    if [ $filled_width -gt 0 ]; then
        bar+=$(printf "%0.s=" $(seq 1 $filled_width))
        if [ $filled_width -lt $bar_width ]; then
            bar+=">"
            empty_width=$((empty_width - 1))
        fi
    fi
    if [ $empty_width -gt 0 ]; then
        bar+=$(printf "%0.s " $(seq 1 $empty_width))
    fi
    bar+="]"

    printf "\r${BLUE}%s: %s ${NC}%s %3d%%" "$title" "$msg" "$bar" "$percent"
    if [ -n "$speed" ]; then
        printf " | ${YELLOW}%s${NC}" "$speed"
    fi
}

# 实时下载进度条
download_with_progress() {
    local url="$1"
    local output_file="$2"
    local title="$3"
    local message="$4"
    local use_original_name="${5:-false}"  # 可选第5个参数：是否使用服务器返回的原始文件名

    local bar_width=$(get_progress_bar_width)

    # 重置进度条状态
    _progress_first_call=

    # 标记下载开始，清除取消标志
    _download_in_progress="true"
    _download_cancelled="false"

    echo ""

    # 清理函数：处理下载结束或取消
    cleanup_download() {
        _download_in_progress="false"
    }

    # 检查下载是否被取消
    check_cancelled() {
        if [ "$_download_cancelled" = "true" ]; then
            echo -e "\n${YELLOW}下载已取消${NC}"
            # 删除不完整的文件
            if [ -n "$output_file" ] && [ -f "$output_file" ]; then
                rm -f "$output_file"
            fi
            cleanup_download
            return 1
        fi
        return 0
    }

    # 优先使用curl（不使用--progress-bar）
    if command -v curl >/dev/null 2>&1; then
        # curl 默认输出格式
        # 使用 stdbuf 避免缓冲，将 \r 转为 \n
        if [ "$use_original_name" = "true" ]; then
            # 使用 -OJ 参数保留服务器返回的原始文件名 (-J 使用 Content-Disposition 头)
            curl -L -OJ --retry 3 --retry-delay 1 --tlsv1.2 --retry-connrefused "$url" 2>&1 | \
            stdbuf -oL tr '\r' '\n' | \
            while IFS= read -r line; do
                # 检查是否被取消
                check_cancelled || { cleanup_download; return 1; }
                # 跳过空行和表头行
                if [[ -z "$line" ]] || [[ "$line" == *"Total"* ]] || [[ "$line" == *"Dload"* ]] || [[ "$line" == *"%"* ]]; then
                    continue
                fi
                local percent=$(echo "$line" | awk '{print $1}')
                local raw_speed=$(echo "$line" | awk '{print $NF}')
                if [[ "$percent" =~ ^[0-9]+$ ]]; then
                    local speed=$(format_speed "$raw_speed")
                    update_progress_bar_with_width "$title" "$message" "$percent" "$bar_width" "$speed"
                fi
            done
        else
            curl -L -o "$output_file" --retry 3 --retry-delay 1 --tlsv1.2 --retry-connrefused "$url" 2>&1 | \
            stdbuf -oL tr '\r' '\n' | \
            while IFS= read -r line; do
                # 检查是否被取消
                check_cancelled || { cleanup_download; return 1; }
                # 跳过空行和表头行
                if [[ -z "$line" ]] || [[ "$line" == *"Total"* ]] || [[ "$line" == *"Dload"* ]] || [[ "$line" == *"%"* ]]; then
                    continue
                fi
                # 使用 awk 解析: 第1列=百分比, 最后一列=速度
                # 格式如: "  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--   0 80.3M    0  521k ..."
                local percent=$(echo "$line" | awk '{print $1}')
                local raw_speed=$(echo "$line" | awk '{print $NF}')
                # 确保 percent 是数字
                if [[ "$percent" =~ ^[0-9]+$ ]]; then
                    local speed=$(format_speed "$raw_speed")
                    update_progress_bar_with_width "$title" "$message" "$percent" "$bar_width" "$speed"
                fi
            done
        fi

        local download_exit_code=$?

        # 清理下载状态
        cleanup_download

        # 检查是否被取消
        if [ "$_download_cancelled" = "true" ]; then
            echo -e "\n${YELLOW}下载已取消${NC}"
            [ -f "$output_file" ] && rm -f "$output_file"
            return 1
        fi

        # 检查下载是否成功
        if [ $download_exit_code -eq 0 ]; then
            if [ "$use_original_name" = "true" ]; then
                # 检查当前目录是否有下载的文件
                local downloaded_file=$(ls -t *.jar *.zip 2>/dev/null | head -1)
                if [ -n "$downloaded_file" ] && [ -f "$downloaded_file" ]; then
                    return 0
                else
                    echo -e "${RED}下载失败!${NC}"
                    return 1
                fi
            elif [ -f "$output_file" ]; then
                return 0
            else
                echo -e "${RED}下载失败!${NC}"
                return 1
            fi
        else
            echo -e "${RED}下载失败!${NC}"
            return 1
        fi
    elif command -v wget >/dev/null 2>&1; then
        # wget 作为备选
        if [ "$use_original_name" = "true" ]; then
            # 使用 --content-disposition 保留服务器返回的原始文件名
            wget --content-disposition -L --retry-connrefused --tries=3 "$url" 2>&1 | \
            while IFS= read -r line; do
                # 检查是否被取消
                check_cancelled || { cleanup_download; return 1; }
                if [[ "$line" =~ ([0-9]+)% ]]; then
                    local percent="${BASH_REMATCH[1]}"
                    local speed=$(echo "$line" | grep -oE '[0-9]+\.?[0-9]*[kKmMgG]/s' | tail -1)
                    if [ -z "$speed" ]; then
                        speed=$(echo "$line" | grep -oE '[0-9]+[kKmM] ' | tail -1)
                    fi
                    local formatted_speed=$(format_speed "$speed")
                    update_progress_bar_with_width "$title" "$message" "$percent" "$bar_width" "$formatted_speed"
                fi
            done

            local download_exit_code=$?
            cleanup_download

            if [ "$_download_cancelled" = "true" ]; then
                echo -e "\n${YELLOW}下载已取消${NC}"
                return 1
            fi

            if [ $download_exit_code -eq 0 ]; then
                local downloaded_file=$(ls -t *.jar *.zip 2>/dev/null | head -1)
                if [ -n "$downloaded_file" ] && [ -f "$downloaded_file" ]; then
                    return 0
                else
                    echo -e "${RED}下载失败!${NC}"
                    return 1
                fi
            else
                echo -e "${RED}下载失败!${NC}"
                return 1
            fi
        else
            wget -O "$output_file" --retry-connrefused --tries=3 "$url" 2>&1 | \
            while IFS= read -r line; do
                # 检查是否被取消
                check_cancelled || { cleanup_download; return 1; }
                if [[ "$line" =~ ([0-9]+)% ]]; then
                    local percent="${BASH_REMATCH[1]}"
                    local speed=$(echo "$line" | grep -oE '[0-9]+\.?[0-9]*[kKmMgG]/s' | tail -1)
                    if [ -z "$speed" ]; then
                        speed=$(echo "$line" | grep -oE '[0-9]+[kKmM] ' | tail -1)
                    fi
                    local formatted_speed=$(format_speed "$speed")
                    update_progress_bar_with_width "$title" "$message" "$percent" "$bar_width" "$formatted_speed"
                fi
            done

            local download_exit_code=$?
            cleanup_download

            if [ "$_download_cancelled" = "true" ]; then
                echo -e "\n${YELLOW}下载已取消${NC}"
                [ -f "$output_file" ] && rm -f "$output_file"
                return 1
            fi

            if [ $download_exit_code -eq 0 ] && [ -f "$output_file" ]; then
                return 0
            else
                echo -e "${RED}下载失败!${NC}"
                return 1
            fi
        fi
    else
        _download_in_progress="false"
        echo -e "${RED}错误: 未找到 wget 或 curl${NC}"
        return 1
    fi
}
# 更新进度条
update_progress_bar_with_width() {
    local title="$1"
    local msg="$2"
    local percent="$3"
    local bar_width="$4"
    local speed="$5"

    # 静态变量：记录是否是第一次调用
    if [[ -z "$_progress_first_call" ]]; then
        _progress_first_call=1
    fi

    local filled_width=$((percent * bar_width / 100))
    local empty_width=$((bar_width - filled_width))

    # 构建进度条（包含外层括号）
    local bar="["
    if [ $filled_width -gt 0 ]; then
        bar+=$(printf "%0.s=" $(seq 1 $filled_width))
        # 添加箭头指示
        if [ $filled_width -lt $bar_width ]; then
            bar+=">"
            empty_width=$((empty_width - 1))
        fi
    fi
    if [ $empty_width -gt 0 ]; then
        bar+=$(printf "%0.s " $(seq 1 $empty_width))
    fi
    bar+="]"

    # 第一次调用时：显示标题和进度条
    if [[ "$_progress_first_call" -eq 1 ]]; then
        # 第一行：标题
        printf "${BLUE}%s: %s${NC}\n" "$title" "$msg"
        # 第二行：进度条和速度
        printf "${GREEN}%s${NC} %3d%%" "$bar" "$percent"
        if [ -n "$speed" ]; then
            printf " | ${YELLOW}%s${NC}" "$speed"
        fi
        # 如果是100%，立即添加✓并换行
        if [ "$percent" = "100" ]; then
            printf " ${GREEN}✓${NC}\n"
            _progress_first_call=
            return
        fi
        _progress_first_call=2
    else
        # 后续调用：只更新第二行
        printf "\r\033[K${GREEN}%s${NC} %3d%%" "$bar" "$percent"
        if [ -n "$speed" ]; then
            printf " | ${YELLOW}%s${NC}" "$speed"
        fi
        # 如果是100%，添加✓并换行
        if [ "$percent" = "100" ]; then
            printf " ${GREEN}✓${NC}\n"
            _progress_first_call=
        fi
    fi
}

# 格式化速度显示
format_speed() {
    local raw_speed="$1"  # 格式如 "6081k", "1.23M"
    if [[ -z "$raw_speed" || "$raw_speed" == "-" ]]; then
        echo ""
        return
    fi

    # 提取数值和单位
    local num=$(echo "$raw_speed" | grep -oE '^[0-9.]+')
    local unit=$(echo "$raw_speed" | grep -oE '[kMGT]$' | tr '[:lower:]' '[:upper:]')
    
    # 转换为字节/秒（curl 使用 1000 进制）
    case "$unit" in
        K) num=$(echo "$num * 1000" | bc -l) ;;
        M) num=$(echo "$num * 1000000" | bc -l) ;;
        G) num=$(echo "$num * 1000000000" | bc -l) ;;
        T) num=$(echo "$num * 1000000000000" | bc -l) ;;
        *) num=$num ;; # 已是 B/s
    esac

    # 转换为友好单位（1024 进制，符合用户习惯）
    if (( $(echo "$num >= 1073741824" | bc -l) )); then
        echo "$(printf "%.1f" $(echo "$num / 1073741824" | bc -l)) GB/s"
    elif (( $(echo "$num >= 1048576" | bc -l) )); then
        echo "$(printf "%.1f" $(echo "$num / 1048576" | bc -l)) MB/s"
    elif (( $(echo "$num >= 1024" | bc -l) )); then
        echo "$(printf "%.1f" $(echo "$num / 1024" | bc -l)) KB/s"
    else
        echo "$(printf "%.0f" $num) B/s"
    fi
}


# 处理无GUI模式
handle_no_gui_mode() {
    # 设置陷阱来捕获 return 语句的错误
    handle_cli_function() {
        # 优先处理 -gof 参数（跳转菜单但不跳过主循环）
        if [ -n "$GOTO_MENU" ]; then
            case "$GOTO_MENU" in
                main_menu)
                    cli_main_menu
                    ;;
                server_management)
                    cli_server_management
                    ;;
                jdk_management)
                    cli_jdk_management
                    ;;
                hp_management)
                    cli_hp_management
                    ;;
                system_settings)
                    cli_system_settings
                    ;;
                *)
                    echo "错误: 未知菜单 '$GOTO_MENU'"
                    exit 1
                    ;;
            esac
            # 执行完后进入 CLI 主菜单循环
            while true; do
                cli_main_menu
                CLI_EXIT_CODE=$?
                # 如果用户选择退出（0），则退出脚本
                if [ "$CLI_EXIT_CODE" = "0" ]; then
                    break
                fi
            done
            return 0
        elif [ -n "$TARGET_FUNCTION" ]; then
            # 直接执行指定函数
            if type "$TARGET_FUNCTION" >/dev/null 2>&1; then
                if [ -n "$SERVER_NAME" ]; then
                    "$TARGET_FUNCTION" "$SERVER_NAME"
                elif [ -n "$JDK_VERSION" ]; then
                    "$TARGET_FUNCTION" "$JDK_VERSION"
                else
                    "$TARGET_FUNCTION"
                fi
            else
                echo "错误: 函数 '$TARGET_FUNCTION' 不存在"
                exit 1
            fi
        elif [ -n "$TARGET_MENU" ]; then
            # 非GUI模式下跳转到对应的CLI菜单
            case "$TARGET_MENU" in
                main_menu)
                    cli_main_menu
                    ;;
                server_management)
                    cli_server_management
                    ;;
                jdk_management)
                    cli_jdk_management
                    ;;
                hp_management)
                    cli_hp_management
                    ;;
                system_settings)
                    cli_system_settings
                    ;;
                *)
                    echo "错误: 未知菜单 '$TARGET_MENU'"
                    exit 1
                    ;;
            esac
        else
            # 进入 CLI 交互式主菜单
            cli_main_menu
            CLI_EXIT_CODE=$?
        fi
    }

    # 调用包装函数
    handle_cli_function
    # 使用存储的退出码
    exit ${CLI_EXIT_CODE:-0}
}

# 处理目标执行
handle_target_execution() {
    # 优先处理 -gof 参数（跳转菜单但不跳过主循环）
    if [ -n "$GOTO_MENU" ]; then
        goto_target_menu "$GOTO_MENU"
        return
    fi
    
    if [ -n "$TARGET_FUNCTION" ]; then
        # 直接执行指定函数
        if type "$TARGET_FUNCTION" >/dev/null 2>&1; then
            if [ -n "$SERVER_NAME" ]; then
                "$TARGET_FUNCTION" "$SERVER_NAME"
            elif [ -n "$JDK_VERSION" ]; then
                "$TARGET_FUNCTION" "$JDK_VERSION"
            else
                "$TARGET_FUNCTION"
            fi
        else
            show_msg "错误" "函数 '$TARGET_FUNCTION' 不存在"
            main_menu
        fi
        
        # 执行完成后进入主菜单循环
        if [ "$NO_GUI" != "true" ]; then
            main_menu
        fi
    elif [ -n "$TARGET_MENU" ]; then
        # 跳转到指定菜单（跳过主循环）
        jump_to_target_menu "$TARGET_MENU"
    fi
}

# 跳转到目标菜单（跳过主循环）
jump_to_target_menu() {
    local target_menu="$1"

    # 根据 NO_GUI 选择 GUI 或 CLI 版本
    case "$target_menu" in
        "main_menu")
            if [ "$NO_GUI" = "true" ]; then
                cli_main_menu
            else
                main_menu
            fi
            ;;
        "server_management")
            if [ "$NO_GUI" = "true" ]; then
                cli_server_management
            else
                server_management
            fi
            ;;
        "jdk_management")
            if [ "$NO_GUI" = "true" ]; then
                cli_jdk_management
            else
                jdk_management
            fi
            ;;
        "hp_management")
            if [ "$NO_GUI" = "true" ]; then
                cli_hp_management
            else
                hp_management
            fi
            ;;
        "system_settings")
            if [ "$NO_GUI" = "true" ]; then
                cli_system_settings
            else
                system_settings
            fi
            ;;
        *)
            if [ "$NO_GUI" = "true" ]; then
                echo "错误: 未知菜单: $target_menu"
            else
                show_msg "错误" "未知菜单: $target_menu"
            fi
            if [ "$NO_GUI" = "true" ]; then
                cli_main_menu
            else
                main_menu
            fi
            ;;
    esac
}

# 跳转到目标菜单（保持主循环）
goto_target_menu() {
    local target_menu="$1"

    # 设置环境变量以便错误处理知道当前上下文
    export CURRENT_MENU="$target_menu"

    # 根据 NO_GUI 选择 GUI 或 CLI 版本
    case "$target_menu" in
        "main_menu")
            if [ "$NO_GUI" = "true" ]; then
                cli_main_menu
            else
                main_menu
            fi
            ;;
        "server_management")
            if [ "$NO_GUI" = "true" ]; then
                cli_server_management
            else
                server_management
            fi
            ;;
        "jdk_management")
            if [ "$NO_GUI" = "true" ]; then
                cli_jdk_management
            else
                jdk_management
            fi
            ;;
        "hp_management")
            if [ "$NO_GUI" = "true" ]; then
                cli_hp_management
            else
                hp_management
            fi
            ;;
        "system_settings")
            if [ "$NO_GUI" = "true" ]; then
                cli_system_settings
            else
                system_settings
            fi
            ;;
        "hp_log_menu")
            if [ "$NO_GUI" = "true" ]; then
                cli_hp_log_menu
            else
                hp_log_menu
            fi
            ;;
        *)
            if [ "$NO_GUI" = "true" ]; then
                echo "错误: 未知菜单: $target_menu"
                cli_main_menu
            else
                show_msg "错误" "未知菜单: $target_menu"
                main_menu
            fi
            ;;
    esac
}

# 保存当前终端设置
save_terminal_settings() {
    if [ -t 0 ]; then
        stty -g > "$CONFIG_DIR/terminal_settings" 2>/dev/null || true
    fi
}

# 恢复终端设置
restore_terminal_settings() {
    if [ -f "$CONFIG_DIR/terminal_settings" ]; then
        stty "$(cat "$CONFIG_DIR/terminal_settings")" 2>/dev/null || true
        rm -f "$CONFIG_DIR/terminal_settings"
    fi
    
    # 额外的终端恢复命令
    stty sane 2>/dev/null || true
    tput reset 2>/dev/null || true
    clear 2>/dev/null || true
}

# 安全的编辑器调用函数
safe_edit_file() {
    local file_path="$1"
    local server_name="$2"
    
    # 保存完整的终端状态
    local original_stty=$(stty -g 2>/dev/null)
    local original_term="$TERM"
    
    # 完全分离输入输出
    exec 3<&0  # 保存原始 STDIN
    exec 4>&1  # 保存原始 STDOUT
    exec 5>&2  # 保存原始 STDERR
    
    # 恢复为标准终端
    exec 0< /dev/tty
    exec 1>/dev/tty
    exec 2>/dev/tty
    
    # 重置终端到已知状态
    stty sane
    stty echo
    stty intr '^C'
    stty quit '^\'
    stty erase '^?'
    tput reset 2>/dev/null || true
    tput init
    printf '\033c'
    clear
    
    # 显示
    echo -e "${BLUE}正在编辑文件: $(basename "$file_path")${NC}"
    echo -e "${YELLOW}使用说明:${NC}"
    echo -e "${YELLOW}• 编辑完成后保存文件${NC}"
    echo -e "${YELLOW}• 使用编辑器命令退出（如 :q 对于vim，Ctrl+X 对于nano）${NC}"
    echo -e "${YELLOW}• 按 Ctrl+C 可以取消编辑并返回${NC}"
    echo -e "${YELLOW}按任意键开始编辑...${NC}"
    read -n 1 -s
    
    # 检查文件是否存在
    if [ ! -f "$file_path" ]; then
        echo "错误: 文件不存在: $file_path"
        echo "按任意键返回..."
        read -n 1
        # 恢复文件描述符
        exec 0<&3
        exec 1>&4
        exec 2>&5
        return 1
    fi
    
    # 检测最佳编辑器
    local editor=$(detect_best_editor)
    if [ -z "$editor" ]; then
        # 如果没有找到编辑器，尝试安装或使用备用方案
        if command -v nano >/dev/null 2>&1; then
            editor="nano"
        else
            echo -e "${RED}错误: 未找到可用的文本编辑器${NC}"
            echo -e "${YELLOW}请安装以下任一编辑器:${NC}"
            echo -e "• nano (推荐): sudo apt install nano"
            echo -e "• vim: sudo apt install vim"
            echo -e "${YELLOW}按任意键返回...${NC}"
            read -n 1 -s
            restore_terminal_settings
            export IN_EDIT_MODE="false"
            export CURRENT_SERVER=""
            return 1
        fi
    fi
    
    # 根据编辑器设置参数
    local editor_cmd
    case "$editor" in
        "vim")
            editor_cmd="vim -c 'set number' -c 'syntax on'"
            ;;
        "vi")
            editor_cmd="vi -c 'set number'"
            ;;
        "nano")
            editor_cmd="nano --linenumbers"
            ;;
        *)
            editor_cmd="$editor"
            ;;
    esac
    
    # 执行编辑命令
    if eval "$editor_cmd" "\"$file_path\""; then
        echo -e "${GREEN}文件编辑完成${NC}"
    else
        local edit_exit_code=$?
        if [ $edit_exit_code -eq 130 ]; then
            echo -e "${YELLOW}编辑已取消${NC}"
        else
            echo -e "${RED}文件编辑过程中出现错误${NC}"
        fi
    fi
    
    echo -e "${YELLOW}按任意键返回管理器...${NC}"
    read -n 1 -s
    
    # 恢复文件描述符
    exec 0<&3
    exec 1>&4
    exec 2>&5
    
    restore_terminal_settings
    
    if [ -n "$original_stty" ]; then
        stty "$original_stty" 2>/dev/null
    fi
    export TERM="$original_term"
    
    return 0
}



# 服务器管理功能

# 服务器管理菜单
server_management() {
    # CLI 模式调用 CLI 版本
    if [ "$NO_GUI" = "true" ]; then
        cli_server_management
        return
    fi

    while true; do
        choice=$(safe_whiptail --nocancel --clear \
            --title "服务器管理" \
            --menu "请选择操作：" 12 50 3 \
            "1" "管理服务器" \
            "2" "创建新服务器" \
            "0" "返回主菜单" \
            3>&1 1>&2 2>&3)

        case $choice in
            1) manage_existing_servers ;;
            2) create_server ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# ============================================
# CLI 服务器管理菜单
# ============================================

cli_server_management() {
    while true; do
        # 清屏
        clear 2>/dev/null || printf "\033[2J\033[H"

        echo ""
        echo "============================================"
        echo "           服务器管理"
        echo "============================================"
        echo ""
        echo "  1) 管理现有服务器"
        echo "  2) 创建新服务器"
        echo "  0) 返回主菜单"
        echo ""
        echo "--------------------------------------------"

        echo -n "请输入选项编号 [0-2]: "
        read -r choice

        # 处理空输入
        if [ -z "$choice" ]; then
            echo ""
            continue
        fi

        case "$choice" in
            1)
                echo ""
                echo ">>> 进入管理现有服务器..."
                echo ""
                cli_manage_servers
                echo ""
                echo -n "按回车键返回... "
                read -r
                ;;
            2)
                echo ""
                echo ">>> 进入创建新服务器..."
                echo ""
                cli_create_server
                echo ""
                echo -n "按回车键返回... "
                read -r
                ;;
            0)
                echo ""
                echo "返回主菜单..."
                echo ""
                break
                ;;
            *)
                echo ""
                echo -e "${RED}无效选项 '$choice'，请重新输入${NC}"
                echo ""
                ;;
        esac
    done
}

# ============================================
# CLI 管理现有服务器
# ============================================

cli_manage_servers() {
    # 获取服务器列表
    local servers_json
    servers_json=$(jq -c '.servers[]' "$CONFIG_FILE" 2>/dev/null)

    if [ -z "$servers_json" ]; then
        echo ""
        echo -e "${YELLOW}没有可用的服务器${NC}"
        echo ""
        echo "提示: 请先创建服务器"
        echo ""
        echo -n "按回车键返回... "
        read -r
        return
    fi

    # 解析服务器列表并构建选项
    local options=()
    while IFS= read -r server; do
        [ -z "$server" ] && continue
        local name type version
        name=$(echo "$server" | jq -r '.name')
        type=$(echo "$server" | jq -r '.type')
        version=$(echo "$server" | jq -r '.version')
        # 添加选项: "name:type version"
        options+=("${name}:${type} ${version}")
    done <<< "$servers_json"

    if [ ${#options[@]} -eq 0 ]; then
        echo ""
        echo -e "${YELLOW}没有可用的服务器${NC}"
        echo ""
        echo "提示: 请先创建服务器"
        echo ""
        echo -n "按回车键返回... "
        read -r
        return
    fi

    echo ""
    echo "============================================"
    echo "         选择要管理的服务器"
    echo "============================================"
    echo ""
    echo "已配置的服务器："
    echo ""

    # 显示服务器列表（带编号）
    local idx=1
    for opt in "${options[@]}"; do
        local name="${opt%%:*}"
        local info="${opt#*:}"
        echo "  ${idx}) ${name} (${info})"
        ((idx++))
    done
    echo ""

    # 选择服务器
    echo -n "请输入服务器编号 [1-${#options[@]}]: "
    read -r choice

    # 验证输入
    if [ -z "$choice" ]; then
        echo ""
        return
    fi

    if ! [[ "$choice" =~ ^[0-9]+$ ]] || [ "$choice" -lt 1 ] || [ "$choice" -gt ${#options[@]} ]; then
        echo ""
        echo -e "${RED}无效选择，请重新输入${NC}"
        echo ""
        return
    fi

    # 获取选中的服务器名称
    local selected="${options[$((choice-1))]}"
    local server_name="${selected%%:*}"

    echo ""
    echo -e "${GREEN}已选择服务器: $server_name${NC}"
    echo ""

    # 进入服务器操作菜单
    cli_server_operations_menu "$server_name"
}

# CLI 服务器操作菜单
cli_server_operations_menu() {
    local server_name="$1"

    while true; do
        echo ""
        echo "=== 服务器: $server_name ==="
        echo ""

        # 检查服务器状态
        if is_server_running "$server_name"; then
            echo "状态: ${GREEN}运行中${NC}"
        else
            echo "状态: ${RED}已停止${NC}"
        fi
        echo ""
        echo "请选择操作："
        echo "  1) 启动服务器"
        echo "  2) 停止服务器"
        echo "  3) 查看日志"
        echo "  4) 配置服务器"
        echo "  5) 备份服务器"
        echo "  6) 管理服务器文件"
        echo "  7) 删除服务器"
        echo "  0) 返回"
        echo ""

        echo -n "请选择 [0-7]: "
        read -r choice

        case "$choice" in
            1) start_server "$server_name" ;;
            2) stop_server "$server_name" ;;
            3) cli_view_server_logs "$server_name" ;;
            4) cli_configure_server "$server_name" ;;
            5) backup_server "$server_name" ;;
            6) cli_manage_server_files "$server_name" ;;
            7)
                if ui_confirm "确定要删除服务器 '$server_name' 吗？此操作不可恢复！"; then
                    # 先从配置中移除，避免删除失败后显示已删除的服务器
                    remove_server_from_config "$server_name"

                    # 删除服务器目录
                    echo ""
                    echo -e "${BLUE}正在删除服务器 '$server_name'...${NC}"
                    rm -rf "$MCSERVER_DIR/$server_name"
                    echo -e "${GREEN}服务器已删除${NC}"
                    echo ""

                    # 返回到服务器列表
                    return
                fi
                ;;
            0)
                return
                ;;
            *)
                echo -e "${RED}无效选项，请重新选择${NC}"
                ;;
        esac
    done
}

# CLI 创建新服务器（简化版，核心流程）
cli_create_server() {
    local server_name server_dir server_type mc_version

    echo ""
    echo "=== 创建新服务器 ==="
    echo ""

    # 循环获取服务器名称
    while true; do
        # 获取服务器名称
        server_name=$(ui_input "请输入服务器名称（只能包含字母、数字、下划线）")

        # 检查是否取消（输入为空）
        if [ -z "$server_name" ]; then
            echo ""
            echo -e "${YELLOW}操作已取消${NC}"
            return
        fi

        # 验证服务器名称格式
        if ! [[ "$server_name" =~ ^[a-zA-Z0-9_]+$ ]]; then
            echo ""
            echo -e "${RED}错误: 服务器名称只能包含字母、数字和下划线${NC}"
            echo ""
            continue
        fi

        # 检查名称长度
        if [ ${#server_name} -lt 3 ]; then
            echo ""
            echo -e "${RED}错误: 服务器名称至少需要3个字符${NC}"
            echo ""
            continue
        fi
        if [ ${#server_name} -gt 20 ]; then
            echo ""
            echo -e "${RED}错误: 服务器名称不能超过20个字符${NC}"
            echo ""
            continue
        fi

        # 检查服务器是否已存在
        if is_server_exists "$server_name"; then
            echo ""
            echo -e "${RED}错误: 服务器 '$server_name' 已存在${NC}"
            echo ""
            continue
        fi

        break
    done

    echo ""
    echo -e "${GREEN}服务器名称: $server_name${NC}"
    echo ""

    # 创建服务器目录
    server_dir="$MCSERVER_DIR/$server_name"
    mkdir -p "$server_dir"

    # CLI 选择服务器类型
    echo "=== 选择服务器类型 ==="
    echo ""
    echo "  1) Java版服务器"
    echo "  2) 基岩版服务器"
    echo ""
    echo -n "请选择 [1-2]: "
    read -r category_choice

    case "$category_choice" in
        1)  # Java版
            echo ""
            echo "=== 选择 Java 版服务器类型 ==="
            echo ""
            echo "  1) Spigot (插件服)"
            echo "  2) PaperMC (高性能)"
            echo "  3) CraftBukkit (传统插件)"
            echo "  4) MohistMC (插件+模组)"
            echo "  5) Fabric (现代模组)"
            echo "  6) Forge (经典模组)"
            echo "  7) Pufferfish (高性能)"
            echo "  8) Purpur (Paper++)"
            echo "  9) NeoForged (Forge分支)"
            echo " 10) Leaves (高性能)"
            echo " 11) Folia (多线程)"
            echo " 12) Vanilla (原版)"
            echo ""
            echo -n "请选择 [1-12]: "
            read -r type_choice

            case "$type_choice" in
                1) server_type="spigot" ;;
                2) server_type="paper" ;;
                3) server_type="craftbukkit" ;;
                4) server_type="mohist" ;;
                5) server_type="fabric" ;;
                6) server_type="forge" ;;
                7) server_type="pufferfish" ;;
                8) server_type="purpur" ;;
                9) server_type="neoforged" ;;
                10) server_type="leaves" ;;
                11) server_type="folia" ;;
                12) server_type="vanilla" ;;
                *) echo "无效选择，使用默认: spigot"; server_type="spigot" ;;
            esac
            ;;
        2)  # 基岩版
            server_type="bedrock"
            ;;
        *)
            echo "无效选择，操作取消"
            rm -rf "$server_dir"
            return
            ;;
    esac

    echo ""
    echo -e "选择的服务器类型: ${GREEN}$server_type${NC}"
    echo ""

    # 获取版本列表并选择版本
    echo "=== 选择版本 ==="
    echo ""

    local versions=()
    get_supported_versions "$server_type" versions

    if [ ${#versions[@]} -eq 0 ]; then
        echo "无法获取版本列表，请重试"
        rm -rf "$server_dir"
        return 1
    fi

    # 显示版本列表
    local i=1
    for ver in "${versions[@]}"; do
        echo "  $i) $ver"
        i=$((i + 1))
    done
    echo ""

    echo -n "请选择版本编号: "
    read -r ver_choice

    if [ -z "$ver_choice" ] || [ "$ver_choice" -lt 1 ] || [ "$ver_choice" -gt ${#versions[@]} ]; then
        echo "无效选择，操作取消"
        rm -rf "$server_dir"
        return
    fi

    mc_version="${versions[$((ver_choice - 1))]}"
    echo ""
    echo -e "选择的版本: ${GREEN}$mc_version${NC}"
    echo ""

    # 下载服务器核心
    echo "=== 下载服务器核心 ==="
    echo ""

    if ! download_server_core "$server_type" "$mc_version" "$server_dir"; then
        echo "服务器核心下载失败"
        rm -rf "$server_dir"
        return 1
    fi

    echo ""
    echo -e "${GREEN}服务器核心下载完成${NC}"
    echo ""

    # 创建启动脚本
    echo "=== 创建启动脚本 ==="
    echo ""

    if ! create_start_script "$server_dir" "$server_type" "$mc_version"; then
        echo "启动脚本创建失败"
        rm -rf "$server_dir"
        return 1
    fi

    echo ""
    echo -e "${GREEN}启动脚本创建完成${NC}"
    echo ""

    # 添加到配置
    local downloaded_core=$(ls -t "$server_dir"/*.jar 2>/dev/null | head -1)
    if [ -n "$downloaded_core" ]; then
        downloaded_core=$(basename "$downloaded_core")
    fi
    add_server_to_config "$server_name" "$server_type" "$mc_version" "$downloaded_core"

    echo ""
    echo "============================================"
    echo -e "  ${GREEN}服务器创建成功！${NC}"
    echo "============================================"
    echo ""
    echo "服务器名称: $server_name"
    echo "服务器类型: $server_type"
    echo "版本: $mc_version"
    echo "路径: $server_dir"
    echo ""
}

# CLI 查看服务器日志
cli_view_server_logs() {
    local server_name="$1"
    local server_dir="$MCSERVER_DIR/$server_name"

    if [ ! -d "$server_dir" ]; then
        echo "错误: 服务器目录不存在"
        return 1
    fi

    # 查找日志文件
    local log_files=()
    if [ -f "$server_dir/logs/latest.log" ]; then
        log_files+=("latest:latest.log")
    fi
    if [ -f "$server_dir/server.log" ]; then
        log_files+=("server:server.log")
    fi

    # 查找其他日志
    for log in "$server_dir"/logs/*.log; do
        [ -f "$log" ] || continue
        local fname=$(basename "$log")
        [[ "$fname" == "latest.log" ]] && continue
        log_files+=("$fname:$fname")
    done

    if [ ${#log_files[@]} -eq 0 ]; then
        echo "没有找到日志文件"
        echo -n "按回车键返回... "
        read -r
        return
    fi

    # 选择日志文件
    local selected
    selected=$(ui_select "选择日志文件" "${log_files[@]}")
    [ $? -ne 0 ] || [ -z "$selected" ] && return

    # 显示日志
    local log_path="$server_dir/logs/$selected"
    [ "$selected" = "server" ] && log_path="$server_dir/server.log"

    if [ -f "$log_path" ]; then
        ui_pager "服务器日志: $server_name" "$(tail -100 "$log_path")"
    else
        echo "日志文件不存在"
    fi
}

# CLI 配置服务器（简化菜单）
cli_configure_server() {
    local server_name="$1"

    if ! is_server_exists "$server_name"; then
        echo "错误: 服务器 '$server_name' 不存在"
        return 1
    fi

    while true; do
        echo ""
        echo "=== 配置服务器: $server_name ==="
        echo ""
        echo "请选择配置项："
        echo "  1) 服务器设置 (server.properties)"
        echo "  2) 服务器名称"
        echo "  3) 端口设置"
        echo "  4) 游戏模式"
        echo "  5) 难度设置"
        echo "  6) 视距设置"
        echo "  7) 在线模式"
        echo "  8) PvP 设置"
        echo "  9) 白名单设置"
        echo " 10) 返回"
        echo ""

        echo -n "请选择 [1-10]: "
        read -r choice

        case "$choice" in
            1) cli_edit_server_properties "$server_name" ;;
            2) cli_change_server_display_name "$server_name" ;;
            3) cli_change_server_port "$server_name" ;;
            4) cli_change_game_mode "$server_name" ;;
            5) cli_change_difficulty "$server_name" ;;
            6) cli_change_view_distance "$server_name" ;;
            7) cli_change_online_mode "$server_name" ;;
            8) cli_change_pvp "$server_name" ;;
            9) cli_change_whitelist "$server_name" ;;
            10)
                return
                ;;
            *)
                echo -e "${RED}无效选项，请重新选择${NC}"
                ;;
        esac
    done
}

# CLI 编辑 server.properties
cli_edit_server_properties() {
    local server_name="$1"
    local server_dir="$MCSERVER_DIR/$server_name"
    local props_file="$server_dir/server.properties"

    if [ ! -f "$props_file" ]; then
        echo "错误: server.properties 文件不存在"
        return 1
    fi

    # 显示当前配置（简化版）
    echo ""
    echo "=== server.properties 配置 ==="
    echo ""
    grep -v "^#" "$props_file" | grep -v "^$" | head -20
    echo ""
    echo "(完整编辑请使用文件管理功能)"
}

# 获取服务器属性
get_server_property() {
    local server_name="$1"
    local key="$2"
    local default="$3"
    local server_dir="$MCSERVER_DIR/$server_name"
    local props_file="$server_dir/server.properties"

    if [ ! -f "$props_file" ]; then
        echo "$default"
        return
    fi

    local value=$(grep "^$key=" "$props_file" | cut -d= -f2-)
    if [ -n "$value" ]; then
        echo "$value"
    else
        echo "$default"
    fi
}

# 设置服务器属性
set_server_property() {
    local server_name="$1"
    local key="$2"
    local value="$3"
    local server_dir="$MCSERVER_DIR/$server_name"
    local props_file="$server_dir/server.properties"

    if [ ! -f "$props_file" ]; then
        echo "错误: server.properties 文件不存在"
        return 1
    fi

    set_property_value "$props_file" "$key" "$value"
}

# CLI 更改服务器显示名称
cli_change_server_display_name() {
    local server_name="$1"
    local current_name=$(get_server_property "$server_name" "motd" "Minecraft Server")

    local new_name
    new_name=$(ui_input "请输入服务器显示名称" "$current_name")

    if [ -n "$new_name" ]; then
        set_server_property "$server_name" "motd" "$new_name"
        echo "服务器显示名称已更新"
    fi
}

# CLI 更改服务器端口
cli_change_server_port() {
    local server_name="$1"
    local current_port=$(get_server_property "$server_name" "server-port" "25565")

    local new_port
    new_port=$(ui_input "请输入服务器端口 (1024-65535)" "$current_port")

    if [ -n "$new_port" ]; then
        if [[ "$new_port" =~ ^[0-9]+$ ]] && [ "$new_port" -ge 1024 ] && [ "$new_port" -le 65535 ]; then
            set_server_property "$server_name" "server-port" "$new_port"
            echo "服务器端口已更新"
        else
            echo "错误: 端口必须是 1024-65535 之间的数字"
        fi
    fi
}

# CLI 更改游戏模式
cli_change_game_mode() {
    local server_name="$1"
    local current_mode=$(get_server_property "$server_name" "gamemode" "survival")

    local choice
    choice=$(ui_select "选择游戏模式" "survival:生存模式" "creative:创造模式" "adventure:冒险模式" "spectator:旁观模式")
    [ $? -ne 0 ] || [ -z "$choice" ] && return

    set_server_property "$server_name" "gamemode" "$choice"
    echo "游戏模式已更新为: $choice"
}

# CLI 更改难度
cli_change_difficulty() {
    local server_name="$1"
    local current_diff=$(get_server_property "$server_name" "difficulty" "easy")

    local choice
    choice=$(ui_select "选择游戏难度" "peaceful:和平" "easy:简单" "normal:普通" "hard:困难")
    [ $? -ne 0 ] || [ -z "$choice" ] && return

    set_server_property "$server_name" "difficulty" "$choice"
    echo "游戏难度已更新为: $choice"
}

# CLI 更改视距
cli_change_view_distance() {
    local server_name="$1"
    local current_distance=$(get_server_property "$server_name" "view-distance" "10")

    local new_distance
    new_distance=$(ui_input "请输入视距 (2-32)" "$current_distance")

    if [ -n "$new_distance" ]; then
        if [[ "$new_distance" =~ ^[0-9]+$ ]] && [ "$new_distance" -ge 2 ] && [ "$new_distance" -le 32 ]; then
            set_server_property "$server_name" "view-distance" "$new_distance"
            echo "视距已更新"
        else
            echo "错误: 视距必须是 2-32 之间的数字"
        fi
    fi
}

# CLI 更改在线模式
cli_change_online_mode() {
    local server_name="$1"
    local current_mode=$(get_server_property "$server_name" "online-mode" "true")

    if ui_confirm "是否启用在线模式？\n启用: 只有正版玩家可以加入\n禁用: 允许离线模式玩家加入\n当前: $current_mode"; then
        set_server_property "$server_name" "online-mode" "true"
        echo "在线模式已启用"
    else
        set_server_property "$server_name" "online-mode" "false"
        echo "在线模式已禁用"
    fi
}

# CLI 更改 PvP
cli_change_pvp() {
    local server_name="$1"
    local current_pvp=$(get_server_property "$server_name" "pvp" "true")

    if ui_confirm "是否允许玩家互相攻击？\n当前: $current_pvp"; then
        set_server_property "$server_name" "pvp" "true"
        echo "PVP 已启用"
    else
        set_server_property "$server_name" "pvp" "false"
        echo "PVP 已禁用"
    fi
}

# CLI 更改白名单
cli_change_whitelist() {
    local server_name="$1"
    local current_wl=$(get_server_property "$server_name" "white-list" "false")

    if ui_confirm "是否启用白名单？\n当前: $current_wl"; then
        set_server_property "$server_name" "white-list" "true"
        echo "白名单已启用"
    else
        set_server_property "$server_name" "white-list" "false"
        echo "白名单已禁用"
    fi
}

# CLI 管理服务器文件
cli_manage_server_files() {
    local server_name="$1"
    local server_dir="$MCSERVER_DIR/$server_name"

    while true; do
        echo ""
        echo "=== 管理服务器文件: $server_name ==="
        echo ""

        # 显示目录结构
        echo "请选择："
        echo "  1) 查看根目录"
        echo "  2) 查看配置文件"
        echo "  3) 查看插件目录 (plugins)"
        echo "  4) 查看 mods 目录"
        echo "  5) 查看日志目录"
        echo "  0) 返回"
        echo ""

        echo -n "请选择 [0-5]: "
        read -r choice

        case "$choice" in
            1) cli_list_server_dir "$server_name" "" ;;
            2) cli_list_server_dir "$server_name" "" ;;
            3)
                if [ -d "$server_dir/plugins" ]; then
                    cli_list_server_dir "$server_name" "plugins"
                else
                    echo "插件目录不存在"
                fi
                ;;
            4)
                if [ -d "$server_dir/mods" ]; then
                    cli_list_server_dir "$server_name" "mods"
                else
                    echo "mods 目录不存在"
                fi
                ;;
            5)
                if [ -d "$server_dir/logs" ]; then
                    cli_list_server_dir "$server_name" "logs"
                else
                    echo "日志目录不存在"
                fi
                ;;
            0)
                return
                ;;
            *)
                echo -e "${RED}无效选项，请重新选择${NC}"
                ;;
        esac
    done
}

# CLI 列出服务器目录内容
cli_list_server_dir() {
    local server_name="$1"
    local subdir="$2"
    local server_dir="$MCSERVER_DIR/$server_name"
    local target_dir="$server_dir/$subdir"

    if [ ! -d "$target_dir" ]; then
        echo "目录不存在: $target_dir"
        return
    fi

    echo ""
    echo "=== 目录: $subdir ==="
    echo ""

    ls -la "$target_dir"
    echo ""
    echo "共 $(ls -1 "$target_dir" | wc -l) 个文件/目录"
}

# 创建新服务器
create_server() {
    local server_name="${1:-}"

    # CLI 模式判断
    if [ "$NO_GUI" = "true" ]; then
        cli_create_server "$server_name"
        return $?
    fi

    # GUI 模式实现（来自桌面版）
    local server_dir server_type mc_version
    local server_type_choice server_category_choice
    local name_confirmed=false  # 服务器名称是否已确认

    # 如果已经传递了服务器名称（来自 CLI 模式），直接验证并创建目录
    if [ -n "$server_name" ]; then
        # 验证服务器名称格式和长度
        if ! [[ "$server_name" =~ ^[a-zA-Z0-9_]+$ ]]; then
            show_msg "错误" "服务器名称只能包含字母、数字和下划线"
            return 1
        fi
        if [ ${#server_name} -lt 3 ]; then
            show_msg "错误" "服务器名称至少需要3个字符"
            return 1
        fi
        if [ ${#server_name} -gt 20 ]; then
            show_msg "错误" "服务器名称不能超过20个字符"
            return 1
        fi

        # 检查是否已存在
        if [ -d "$MCSERVER_DIR/$server_name" ]; then
            show_msg "错误" "服务器 '$server_name' 已存在"
            return 1
        fi

        # 创建服务器目录
        server_dir="$MCSERVER_DIR/$server_name"
        mkdir -p "$server_dir"

        # 标记名称已确认
        name_confirmed=true
    else
        # 外层循环：服务器名称输入
        while true; do
            # 获取服务器名称
        server_name=$(safe_whiptail --inputbox "请输入服务器名称（只能包含字母、数字、下划线）：" 8 40 3>&1 1>&2 2>&3)
        local input_result=$?

        if [ $input_result -ne 0 ] || [ -z "$server_name" ]; then
            # 用户取消输入名称，直接返回
            return
        fi

        # 验证服务器名称格式和长度
        if ! [[ "$server_name" =~ ^[a-zA-Z0-9_]+$ ]]; then
            show_msg "错误" "服务器名称只能包含字母、数字和下划线"
            continue
        fi

        # 检查名称长度
        if [ ${#server_name} -lt 3 ]; then
            show_msg "错误" "服务器名称至少需要3个字符"
            continue
        fi
        if [ ${#server_name} -gt 20 ]; then
            show_msg "错误" "服务器名称不能超过20个字符"
            continue
        fi

        # 检查是否已存在
        if [ -d "$MCSERVER_DIR/$server_name" ]; then
            show_msg "错误" "服务器 '$server_name' 已存在"
            continue
        fi

        # 创建服务器目录
        server_dir="$MCSERVER_DIR/$server_name"
        mkdir -p "$server_dir"

        # 标记名称已确认，跳出名称输入循环
        name_confirmed=true
        break
    done

    fi  # 结束 if server_name 传递检查

    # 服务器名称确认后，进入类型选择
    if [ "$name_confirmed" = "true" ]; then
        while true; do
        # 选择服务器大类
        server_category_choice=$(safe_whiptail --menu "选择服务器类型：" 15 50 5 \
            "java" "Java版服务器" \
            "bedrock" "基岩版服务器" \
            3>&1 1>&2 2>&3)

        if [ $? -ne 0 ]; then
            rm -rf "$server_dir"
            return
        fi

        case $server_category_choice in
            "java")
                # Java版服务器类型选择
                server_type_choice=$(safe_whiptail --menu "选择Java版服务器类型：" 22 60 13 \
                    "1" "Spigot (插件服)" \
                    "2" "PaperMC (高性能)" \
                    "3" "CraftBukkit (传统插件)" \
                    "4" "MohistMC (插件+模组)" \
                    "5" "LiteLoader (轻量模组)" \
                    "6" "Fabric (现代模组)" \
                    "7" "Forge (经典模组)" \
                    "8" "SpongePowered (API丰富)" \
                    "9" "QuiltMC (Fabric分支)" \
                    "10" "Pufferfish (Paper优化)" \
                    "11" "Purpur (Paper++优化)" \
                    "12" "NeoForged (Forge分支)" \
                    "13" "Leaves (高性能)" \
                    "14" "Leaf (轻量级)" \
                    "15" "Folia (多线程)" \
                    "16" "SpongeVanilla (独立API)" \
                    "17" "Vanilla (原版)" \
                    3>&1 1>&2 2>&3)

                if [ $? -ne 0 ]; then
                    continue
                fi

                case $server_type_choice in
                    1) server_type="spigot" ;;
                    2) server_type="paper" ;;
                    3) server_type="craftbukkit" ;;
                    4) server_type="mohist" ;;
                    5) server_type="liteloader" ;;
                    6) server_type="fabric" ;;
                    7) server_type="forge" ;;
                    8) server_type="spongeforge" ;;
                    9) server_type="quilt" ;;
                    10) server_type="pufferfish" ;;
                    11) server_type="purpur" ;;
                    12) server_type="neoforged" ;;
                    13) server_type="leaves" ;;
                    14) server_type="leaf" ;;
                    15) server_type="folia" ;;
                    16) server_type="spongevanilla" ;;
                    17) server_type="vanilla" ;;
                    *) continue ;;
                esac
                ;;

            "bedrock")
                # 基岩版服务器类型选择
                server_type_choice=$(safe_whiptail --menu "选择基岩版服务器类型：" 12 50 2 \
                    "1" "Bedrock （官方）" \
                    "2" "Nukkit (PE服务端)" \
                    3>&1 1>&2 2>&3)

                if [ $? -ne 0 ]; then
                    continue
                fi

                case $server_type_choice in
                    1) server_type="bedrock" ;;
                    2) server_type="nukkit" ;;
                    *) continue ;;
                esac
                ;;

            *)
                continue
                ;;
        esac

        # 获取该服务器类型支持的版本列表
        local supported_versions=()
        get_supported_versions "$server_type" supported_versions

        if [ ${#supported_versions[@]} -eq 0 ]; then
            show_msg "错误" "无法获取 $server_type 支持的版本列表"
            continue
        fi

        # 构建版本选择菜单
        local version_list=()
        for version in "${supported_versions[@]}"; do
            if [ "$version" = "custom" ]; then
                version_list+=("custom" "输入自定义版本")
            else
                # 为每个版本添加推荐标记
                local recommended=""
                case "$server_type" in
                    "vanilla"|"spigot"|"paper"|"")
                        if [ "$version" = "1.20.6" ] || [ "$version" = "1.21.1" ]; then
                            recommended="(推荐)"
                        fi
                        ;;
                    "forge"|"neoforged")
                        if [ "$version" = "1.20.1" ] || [ "$version" = "1.19.2" ]; then
                            recommended="(模组丰富)"
                        fi
                        ;;
                    "fabric"|"quilt")
                        if [ "$version" = "1.20.1" ] || [ "$version" = "1.21.1" ]; then
                            recommended="(推荐)"
                        fi
                        ;;
                    "bedrock")
                        if [ "$version" = "1.20.80" ] || [ "$version" = "1.21.1" ]; then
                            recommended="(稳定)"
                        fi
                        ;;
                    "mohist")
                        if [ "$version" = "1.12.2" ] || [ "$version" = "1.16.5" ]; then
                            recommended="(兼容性好)"
                        fi
                        ;;
                    "pufferfish"|"purpur"|"leaves"|"leaf")
                        if [ "$version" = "1.20.1" ] || [ "$version" = "1.21.1" ]; then
                            recommended="(高性能)"
                        fi
                        ;;
                esac
                version_list+=("$version" "$recommended")
            fi
        done

        # 选择Minecraft版本
        mc_version=$(safe_whiptail --title "选择Minecraft版本" \
            --menu "服务器类型: $server_type" \
            20 60 12 "${version_list[@]}" 3>&1 1>&2 2>&3)

        if [ $? -ne 0 ]; then
            # 版本选择取消，询问用户操作
            local choice=$(safe_whiptail --menu "版本选择已取消。请选择操作：" 12 50 3 \
                "1" "重新选择服务器类型" \
                "2" "重新输入服务器名称" \
                "3" "取消创建服务器" \
                3>&1 1>&2 2>&3)

            case $choice in
                1)
                    # 重新选择类型，继续内层循环
                    continue
                    ;;
                2)
                    # 重新输入名称，跳出内层循环
                    rm -rf "$server_dir"
                    break
                    ;;
                3|*)
                    # 取消创建，清理目录并返回
                    rm -rf "$server_dir"
                    return
                    ;;
            esac
        fi

        if [ -z "$mc_version" ]; then
            show_msg "错误" "必须选择版本"
            continue
        fi

        # 处理自定义版本
        if [ "$mc_version" = "custom" ]; then
            mc_version=$(safe_whiptail --inputbox "请输入自定义Minecraft版本号：" 8 40 "1.20.1" 3>&1 1>&2 2>&3)
            if [ $? -ne 0 ]; then
                # 自定义版本输入取消，重新选择版本
                continue
            fi

            if [ -z "$mc_version" ]; then
                show_msg "错误" "版本号不能为空"
                continue
            fi

            # 验证版本格式
            if ! validate_version_format "$mc_version" "$server_type"; then
                if [ "$server_type" = "bedrock" ]; then
                    show_msg "错误" "基岩版版本号格式不正确，应为: X.X.X.X (如 1.26.1.1)"
                else
                    show_msg "错误" "版本号格式不正确，应为: X.X.X 或 X.X"
                fi
                continue
            fi

            # 验证自定义版本是否受支持
            if ! validate_custom_version "$server_type" "$mc_version"; then
                safe_whiptail --yesno "警告: $server_type 可能不完全支持版本 $mc_version\n\n是否继续尝试？" 10 60
                if [ $? -ne 0 ]; then
                    continue
                fi
            fi
        fi

        # 显示服务器配置摘要
        local summary="服务器配置摘要:\n\n"
        summary+="名称: $server_name\n"
        summary+="类型: $server_type\n"
        summary+="版本: $mc_version\n"
        summary+="路径: $server_dir\n\n"

        # 获取版本兼容性信息
        local compatibility_info=$(get_version_compatibility_info "$server_type" "$mc_version")
        summary+="$compatibility_info\n"

        # 添加特定服务器类型的注意事项
        case "$server_type" in
            "bedrock")
                summary+="\n⚠️  基岩版服务器注意事项:\n"
                summary+="• 原生C++编写，无需Java环境\n"
                summary+="• 支持跨平台连接（Win10/11, iOS, Android, Xbox）\n"
                summary+="• 性能优秀，资源占用低\n"
                summary+="• 需要同意EULA协议\n"
                ;;
            "mohist")
                summary+="\n⚠️  混合服务器注意事项:\n"
                summary+="• 同时支持插件和模组\n"
                summary+="• 需要更多内存（建议4GB+）\n"
                summary+="• 兼容性可能不如纯插件/模组服\n"
                ;;
            "pufferfish"|"purpur"|"leaves"|"leaf")
                summary+="\n⚡ 高性能服务器注意事项:\n"
                summary+="• 针对性能深度优化\n"
                summary+="• 适合大型服务器和高玩家数\n"
                summary+="• 可能有特殊配置选项\n"
                ;;
        esac

        # 确认创建
        safe_whiptail --yesno "$summary\n确认创建服务器？" 20 70
        if [ $? -ne 0 ]; then
            # 用户取消确认，询问操作
            local confirm_choice=$(safe_whiptail --menu "服务器创建已取消。请选择操作：" 12 50 3 \
                "1" "重新配置服务器" \
                "2" "重新输入服务器名称" \
                "3" "取消创建" \
                3>&1 1>&2 2>&3)

            case $confirm_choice in
                1)
                    # 重新配置，继续内层循环
                    continue
                    ;;
                2)
                    # 重新输入名称，跳出内层循环
                    rm -rf "$server_dir"
                    break
                    ;;
                3|*)
                    # 取消创建，清理目录并返回
                    rm -rf "$server_dir"
                    return
                    ;;
            esac
        fi

        # 下载服务器核心
        if download_server_core "$server_type" "$mc_version" "$server_dir" "$server_name"; then
            # 获取下载的核心文件名
            local downloaded_core=$(ls -t "$server_dir"/*.jar 2>/dev/null | head -1)
            if [ -n "$downloaded_core" ]; then
                downloaded_core=$(basename "$downloaded_core")
            fi

            # 对于Java服务器，自动选择适合的JDK版本
            local recommended_jdk=""
            if [ "$server_category_choice" = "java" ]; then
                recommended_jdk=$(get_recommended_jdk_for_version "$mc_version")
            fi

            # 创建启动脚本
            if create_start_script "$server_dir" "$server_type" "$mc_version" "$recommended_jdk"; then
                # 添加到服务器配置（包含核心文件名）
                add_server_to_config "$server_name" "$server_type" "$mc_version" "$downloaded_core"

                show_msg "成功" "服务器 '$server_name' 创建成功！\n\n类型: $server_type\n版本: $mc_version\n路径: $server_dir"

                # 询问是否立即启动服务器
                safe_whiptail --yesno "是否立即启动服务器？" 8 50
                if [ $? -eq 0 ]; then
                    start_server "$server_name"
                fi
            else
                show_msg "错误" "启动脚本创建失败"
                rm -rf "$server_dir"
                return 1
            fi
        else
            show_msg "错误" "服务器核心下载失败"
            rm -rf "$server_dir"
            return 1
        fi

        # 创建成功，跳出循环
        break
    done

    # 结束 if 语句
    fi
}

# 获取服务器类型支持的版本列表
get_supported_versions() {
    local server_type="$1"
    local -n versions_ref="$2"  # 使用nameref来修改数组

    # 先加载硬编码的版本列表（作为后备）
    local -A hardcoded_versions=()
    case "$server_type" in
        "vanilla")
            # Vanilla 官方原版
            hardcoded_versions=(
                ["1.21.11"]=1 ["1.21.10"]=1 ["1.21.9"]=1 ["1.21.8"]=1 ["1.21.7"]=1 ["1.21.6"]=1 ["1.21.5"]=1 ["1.21.4"]=1 ["1.21.3"]=1 ["1.21.2"]=1 ["1.21.1"]=1 ["1.21"]=1
                ["1.20.6"]=1 ["1.20.5"]=1 ["1.20.4"]=1 ["1.20.3"]=1 ["1.20.2"]=1 ["1.20.1"]=1 ["1.20"]=1
                ["1.19.4"]=1 ["1.19.3"]=1 ["1.19.2"]=1 ["1.19.1"]=1 ["1.19"]=1
                ["1.18.2"]=1 ["1.18.1"]=1 ["1.18"]=1
                ["1.17.1"]=1 ["1.17"]=1
                ["1.16.5"]=1 ["1.16.4"]=1 ["1.16.3"]=1 ["1.16.2"]=1 ["1.16.1"]=1 ["1.16"]=1
                ["1.15.2"]=1 ["1.15.1"]=1 ["1.15"]=1
                ["1.14.4"]=1 ["1.14.3"]=1 ["1.14.2"]=1 ["1.14.1"]=1 ["1.14"]=1
                ["1.13.2"]=1 ["1.13.1"]=1 ["1.13"]=1
                ["1.12.2"]=1 ["1.12.1"]=1 ["1.12"]=1
                ["1.11.2"]=1 ["1.11.1"]=1 ["1.11"]=1
                ["1.10.2"]=1 ["1.10.1"]=1 ["1.10"]=1
                ["1.9.4"]=1 ["1.9.3"]=1 ["1.9.2"]=1 ["1.9.1"]=1 ["1.9"]=1
                ["1.8.9"]=1 ["1.8.8"]=1 ["1.8.7"]=1 ["1.8.6"]=1 ["1.8.5"]=1 ["1.8.4"]=1 ["1.8.3"]=1 ["1.8.2"]=1 ["1.8.1"]=1 ["1.8"]=1
                ["1.7.10"]=1 ["1.7.9"]=1 ["1.7.8"]=1 ["1.7.7"]=1 ["1.7.6"]=1 ["1.7.5"]=1 ["1.7.4"]=1 ["1.7.3"]=1 ["1.7.2"]=1 ["1.7.1"]=1 ["1.7"]=1
            )
            ;;
        "forge"|"neoforged")
            # Forge模组服
            hardcoded_versions=(
                ["1.21.11"]=1 ["1.21.10"]=1 ["1.21.9"]=1 ["1.21.8"]=1 ["1.21.7"]=1 ["1.21.6"]=1 ["1.21.5"]=1 ["1.21.4"]=1 ["1.21.3"]=1 ["1.21.1"]=1 ["1.21"]=1
                ["1.20.6"]=1 ["1.20.4"]=1 ["1.20.3"]=1 ["1.20.2"]=1 ["1.20.1"]=1 ["1.20"]=1
                ["1.19.4"]=1 ["1.19.3"]=1 ["1.19.2"]=1 ["1.19.1"]=1 ["1.19"]=1
                ["1.18.2"]=1 ["1.18.1"]=1 ["1.18"]=1
                ["1.17.1"]=1
                ["1.16.5"]=1 ["1.16.4"]=1 ["1.16.3"]=1 ["1.16.2"]=1 ["1.16.1"]=1
                ["1.15.2"]=1 ["1.15.1"]=1 ["1.15"]=1
                ["1.14.4"]=1 ["1.14.3"]=1 ["1.14.2"]=1
                ["1.13.2"]=1
                ["1.12.2"]=1 ["1.12.1"]=1 ["1.12"]=1
                ["1.11.2"]=1 ["1.11"]=1
                ["1.10.2"]=1 ["1.10"]=1
                ["1.9.4"]=1 ["1.9"]=1
                ["1.8.9"]=1 ["1.8.8"]=1 ["1.8"]=1
                ["1.7.10"]=1 ["1.7.2"]=1
                ["1.6.4"]=1 ["1.6.3"]=1 ["1.6.2"]=1 ["1.6.1"]=1
                ["1.5.2"]=1
            )
            ;;
        "fabric"|"quilt")
            # Fabric轻量模组平台
            hardcoded_versions=(
                ["1.21.11"]=1 ["1.21.10"]=1 ["1.21.9"]=1 ["1.21.8"]=1 ["1.21.7"]=1 ["1.21.6"]=1 ["1.21.5"]=1 ["1.21.4"]=1 ["1.21.3"]=1 ["1.21.2"]=1 ["1.21.1"]=1 ["1.21"]=1
                ["1.20.6"]=1 ["1.20.5"]=1 ["1.20.4"]=1 ["1.20.3"]=1 ["1.20.2"]=1 ["1.20.1"]=1 ["1.20"]=1
                ["1.19.4"]=1 ["1.19.3"]=1 ["1.19.2"]=1 ["1.19.1"]=1 ["1.19"]=1
                ["1.18.2"]=1 ["1.18.1"]=1 ["1.18"]=1
                ["1.17.1"]=1 ["1.17"]=1
                ["1.16.5"]=1 ["1.16.4"]=1 ["1.16.3"]=1 ["1.16.2"]=1 ["1.16.1"]=1 ["1.16"]=1
                ["1.15.2"]=1 ["1.15.1"]=1 ["1.15"]=1
                ["1.14.4"]=1 ["1.14.3"]=1 ["1.14.2"]=1 ["1.14.1"]=1 ["1.14"]=1
            )
            ;;
    esac

    # 尝试从API获取版本列表
    local api_versions=$(get_versions_from_api "$server_type" 2>/dev/null)

    # 合并版本列表
    versions_ref=()

    # 先添加API版本（最新）
    if [ -n "$api_versions" ]; then
        for version in $api_versions; do
            versions_ref+=("$version")
        done
    fi

    # 再添加硬编码版本（去重）- 需要排序
    # 将硬编码版本提取到数组并排序
    local sorted_hardcoded=()
    while IFS= read -r version; do
        sorted_hardcoded+=("$version")
    done < <(printf '%s\n' "${!hardcoded_versions[@]}" | sort -V -r)

    for version in "${sorted_hardcoded[@]}"; do
        # 检查是否已在列表中
        local found=0
        for existing in "${versions_ref[@]}"; do
            if [ "$existing" = "$version" ]; then
                found=1
                break
            fi
        done
        if [ $found -eq 0 ]; then
            versions_ref+=("$version")
        fi
    done

    # 如果API获取失败且没有硬编码版本
    if [ -z "$api_versions" ] && [ ${#hardcoded_versions[@]} -eq 0 ]; then
        versions_ref=("custom")
    else
        # 添加自定义选项
        versions_ref+=("custom")
    fi

    return 0
}

# 验证版本格式
validate_version_format() {
    local version="$1"
    local server_type="${2:-}"

    # 基岩版支持四段式版本号 (如 1.26.1.1)，Java版支持 X.X 或 X.X.X
    if [ "$server_type" = "bedrock" ]; then
        # 基岩版: X.X.X.X 格式
        if ! [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
            return 1
        fi
    else
        # Java版: X.X 或 X.X.X 格式
        if ! [[ "$version" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then
            return 1
        fi
    fi

    # 验证版本号范围
    local major=$(echo "$version" | awk -F. '{print $1}')
    local minor=$(echo "$version" | awk -F. '{print $2}')

    # Minecraft 版本号基本验证
    if [ "$major" -ne 1 ]; then
        return 1
    fi

    # 基岩版 minor version 可以超过 21 (如 1.26.x.x)
    if [ "$server_type" != "bedrock" ]; then
        if [ "$minor" -lt 0 ] || [ "$minor" -gt 21 ]; then
            return 1
        fi
    fi

    return 0
}

# 验证自定义版本
validate_custom_version() {
    local server_type="$1"
    local version="$2"
    
    local major=$(echo "$version" | awk -F. '{print $1}')
    local minor=$(echo "$version" | awk -F. '{print $2}')
    
    # 各服务器核心的最低支持版本检查
    case "$server_type" in
        "vanilla")
            # Vanilla 官方支持 1.0+ 但建议 1.7.2+
            if [ "$major" -eq 1 ] && [ "$minor" -lt 7 ]; then
                echo "警告: Vanilla 对 1.7 以下版本支持可能不完善"
                return 1
            fi
            ;;
        "paper"|"spigot"|"pufferfish"|"purpur"|"leaves"|"leaf")
            # Paper 系列主要支持 1.8+
            if [ "$major" -eq 1 ] && [ "$minor" -lt 8 ]; then
                echo "错误: Paper 系列不支持 1.8 以下版本"
                return 1
            fi
            ;;
        "folia")
            # Folia 主要支持 1.19+
            if [ "$major" -eq 1 ] && [ "$minor" -lt 19 ]; then
                echo "警告: Folia 对 1.19 以下版本支持有限"
                return 1
            fi
            ;;
        "forge"|"neoforged")
            # Forge 支持 1.6.4+
            if [ "$major" -eq 1 ] && [ "$minor" -lt 6 ]; then
                echo "错误: Forge 不支持 1.6 以下版本"
                return 1
            fi
            ;;
        "fabric"|"quilt")
            # Fabric 支持 1.14+
            if [ "$major" -eq 1 ] && [ "$minor" -lt 14 ]; then
                echo "错误: Fabric 不支持 1.14 以下版本"
                return 1
            fi
            ;;
        "bedrock")
            # 基岩版版本检查
            if [ "$major" -eq 1 ] && [ "$minor" -lt 2 ]; then
                echo "警告: 基岩版 1.2 以下版本可能不完整"
                return 1
            fi

            # 基岩版系统架构检查 (仅支持 amd64 + Ubuntu/Windows)
            local os_type=$(uname -s)
            local arch=$(uname -m)

            case "$os_type" in
                "Linux")
                    # 基岩版 Linux 版仅支持 Ubuntu 22.04+
                    if [ "$arch" != "x86_64" ] && [ "$arch" != "amd64" ]; then
                        echo "错误: 基岩版 Linux 版仅支持 amd64 (x86_64) 架构"
                        return 1
                    fi
                    # 检查是否为 Ubuntu
                    if [ -f /etc/os-release ]; then
                        . /etc/os-release
                        if [ "$ID" != "ubuntu" ]; then
                            echo "警告: 基岩版 Linux 版仅官方支持 Ubuntu 22.04 LTS，其他发行版可能无法运行"
                        elif [ "${VERSION_ID%%.*}" -lt 22 ]; then
                            echo "错误: 基岩版 Linux 版需要 Ubuntu 22.04 LTS 或更高版本"
                            return 1
                        fi
                    else
                        echo "警告: 无法检测 Linux 发行版，基岩版可能无法运行"
                    fi
                    ;;
                "MINGW"*|"MSYS"*|"CYGWIN"*|"Windows_NT")
                    # Windows 版支持 amd64
                    if [ "$arch" != "x86_64" ] && [ "$arch" != "amd64" ]; then
                        echo "错误: 基岩版 Windows 版仅支持 amd64 (x86_64) 架构"
                        return 1
                    fi
                    ;;
                *)
                    echo "错误: 基岩版仅支持 Linux (Ubuntu) 和 Windows 系统"
                    return 1
                    ;;
            esac
            ;;
    esac
    
    return 0
}

# 获取版本兼容性信息
get_version_compatibility_info() {
    local server_type="$1"
    local version="$2"
    
    local info=""
    local major=$(echo "$version" | awk -F. '{print $1}')
    local minor=$(echo "$version" | awk -F. '{print $2}')
    
    case "$server_type" in
        "vanilla")
            info="✅ Vanilla 官方原版，兼容性最佳"
            if [ "$major" -eq 1 ] && [ "$minor" -lt 7 ]; then
                info="⚠️  较旧版本，部分功能可能受限"
            fi
            ;;
        "paper")
            info="⚡⚡ Paper 高性能优化，插件兼容性好"
            if [ "$major" -eq 1 ] && [ "$minor" -lt 12 ]; then
                info="⚡⚡ Paper 优化版，部分新插件可能不兼容"
            fi
            ;;
        "spigot")
            info="🔌🔌 Spigot 插件丰富，社区支持完善"
            if [ "$major" -eq 1 ] && [ "$minor" -lt 12 ]; then
                info="🔌🔌 经典版本，插件生态成熟"
            fi
            ;;
        "folia")
            info="🚀🚀🚀🚀 Folia 多线程高性能，适合大型服务器"
            if [ "$major" -eq 1 ] && [ "$minor" -ge 20 ]; then
                info+="\n✅ 完美支持多线程区域系统"
            elif [ "$major" -eq 1 ] && [ "$minor" -eq 19 ]; then
                info+="\n⚠️  早期版本，部分功能可能受限"
            fi
            ;;
        "forge")
            info="🔧🔧 Forge 模组强大，适合大型模组包"
            if [ "$major" -eq 1 ] && [ "$minor" -eq 20 ]; then
                info="🔧🔧 当前主流模组版本，生态丰富"
            elif [ "$major" -eq 1 ] && [ "$minor" -eq 19 ]; then
                info="🔧🔧 稳定模组版本，兼容性好"
            elif [ "$major" -eq 1 ] && [ "$minor" -eq 18 ]; then
                info="🔧🔧 长期支持版本，模组稳定"
            elif [ "$major" -eq 1 ] && [ "$minor" -eq 16 ]; then
                info="🔧🔧 经典模组版本，生态完善"
            elif [ "$major" -eq 1 ] && [ "$minor" -eq 12 ]; then
                info="🔧🔧 怀旧模组版本，经典模组丰富"
            fi
            ;;
        "fabric")
            info="✨ Fabric 轻量快速，现代模组平台"
            if [ "$major" -eq 1 ] && [ "$minor" -lt 16 ]; then
                info="✨ Fabric 对新版本优化更好"
            fi
            ;;
        "quilt")
            info="🧵 Quilt Fabric分支，社区驱动"
            ;;
        "pufferfish")
            info="🐡 Pufferfish Paper优化，性能极佳"
            ;;
        "purpur")
            info="🍂 Purpur Paper++，功能丰富"
            ;;
        "leaves")
            info="🍃 Leaves 高性能，适合大型服"
            ;;
        "leaf")
            info="🌿 Leaf 轻量级，资源占用低"
            ;;
        "mohist")
            info="🔌+🔧 混合服务器，插件模组共存"
            ;;
        "liteloader")
            info="⚡ LiteLoader 轻量模组加载器"
            ;;
        "sponge")
            info="🧽 Sponge 现代化API平台"
            ;;
        "neoforged")
            info="🔄 NeoForged Forge分支，活跃开发"
            ;;
        "bedrock")
            info="📱📱 基岩版专用，跨平台连接"
            info+="\n✅ 原生性能，无需Java环境"
            info+="\n🌍 支持Win10/11, iOS, Android, Xbox"
            info+="\n⚠️  系统要求: amd64 + Ubuntu 22.04+ 或 Windows"
            ;;
        *)
            info="ℹ️  标准服务器"
            ;;
    esac

    # Bedrock 不需要JDK，跳过
    if [ "$server_type" = "bedrock" ]; then
        echo "$info"
        return
    fi

    # 添加JDK要求信息
    local required_jdk=$(get_required_jdk_version "$version")
    info+="\n☕ 需要 JDK: $required_jdk+"

    echo "$info"
}

# 获取推荐的JDK版本
get_recommended_jdk_for_version() {
    local mc_version="$1"
    
    # 更精确的JDK版本推荐
    local major=$(echo "$mc_version" | awk -F. '{print $1}')
    local minor=$(echo "$mc_version" | awk -F. '{print $2}')
    local patch=$(echo "$mc_version" | awk -F. '{print $3}')
    
    # 根据Minecraft官方要求和实际兼容性推荐
    if [ "$major" -eq 1 ]; then
        case "$minor" in
            21) echo "21" ;;  # 1.21+ 需要 Java 21
            20) echo "17" ;;  # 1.20+ 需要 Java 17
            19) echo "17" ;;  # 1.19+ 需要 Java 17
            18) echo "17" ;;  # 1.18+ 需要 Java 17
            17) echo "16" ;;  # 1.17+ 需要 Java 16
            16) echo "11" ;;  # 1.16+ 需要 Java 8-11
            15|14|13|12) echo "8" ;;  # 1.12-1.15 需要 Java 8
            11|10|9|8|7) echo "8" ;;   # 1.7-1.11 需要 Java 8
            *) echo "17" ;;   # 默认使用 Java 17
        esac
    else
        echo "17"  # 未来版本默认使用 Java 17
    fi
}

# 添加服务器到配置
add_server_to_config() {
    local name="$1"
    local type="$2"
    local version="$3"
    local core_file="$4"  # 可选：服务器核心文件名

    local temp_file="$CONFIG_FILE.tmp"

    if [ -n "$core_file" ]; then
        jq --arg name "$name" \
           --arg type "$type" \
           --arg version "$version" \
           --arg core_file "$core_file" \
           '.servers += [{"name": $name, "type": $type, "version": $version, "core_file": $core_file}]' \
           "$CONFIG_FILE" > "$temp_file" && mv "$temp_file" "$CONFIG_FILE"
    else
        jq --arg name "$name" \
           --arg type "$type" \
           --arg version "$version" \
           '.servers += [{"name": $name, "type": $type, "version": $version}]' \
           "$CONFIG_FILE" > "$temp_file" && mv "$temp_file" "$CONFIG_FILE"
    fi
}

# 更新服务器核心文件名
update_server_core_file() {
    local server_name="$1"
    local core_file="$2"

    local temp_file="$CONFIG_FILE.tmp"

    jq --arg name "$server_name" \
       --arg core_file "$core_file" \
       '(.servers[] | select(.name == $name)).core_file = $core_file' \
       "$CONFIG_FILE" > "$temp_file" && mv "$temp_file" "$CONFIG_FILE"
}

# 带进度条的解压函数（使用现有的 update_progress_bar_with_width）
unzip_with_progress() {
    local zip_file="$1"
    local output_dir="$2"

    # 使用 Python 进行带进度条的解压（更可靠）
    if command -v python3 >/dev/null 2>&1 || command -v python >/dev/null 2>&1; then
        local python_cmd=$(command -v python3 >/dev/null 2>&1 && echo "python3" || echo "python")
        local bar_width=$(get_progress_bar_width)

        $python_cmd - "$zip_file" "$output_dir" "$bar_width" << 'PYEOF'
import zipfile
import sys
import os
import time

zip_path = sys.argv[1]
output_dir = sys.argv[2]
bar_width = int(sys.argv[3])

# 初始化进度条状态
_progress_called = False

def update_progress(extracted, total):
    global _progress_called
    percent = int(extracted * 100 / total) if total > 0 else 0
    filled = int(bar_width * extracted / total) if total > 0 else 0
    bar = '=' * filled + '-' * (bar_width - filled)

    if not _progress_called:
        print(f"\n正在解压: {extracted}/{total} 文件")
        print(f"[{bar}] {percent}%", end='', flush=True)
        _progress_called = True
    else:
        # 回到行首并更新
        sys.stdout.write(f'\r[{bar}] {percent}% ({extracted}/{total})')
        sys.stdout.flush()

    if extracted == total:
        print()  # 完成后换行

try:
    with zipfile.ZipFile(zip_path, 'r') as z:
        total = len(z.namelist())
        extracted = 0

        for member in z.namelist():
            z.extract(member, output_dir)
            extracted += 1

            # 每解压 100 个文件更新一次进度（避免太频繁）
            if extracted % 100 == 0 or extracted == total:
                update_progress(extracted, total)

    print("解压完成")
    sys.exit(0)
except Exception as e:
    print(f"\n解压失败: {e}", file=sys.stderr)
    sys.exit(1)
PYEOF
        return $?
    else
        # 没有 Python，使用普通解压
        echo -e "${YELLOW}Python 不可用，使用普通解压${NC}"
        unzip -q "$zip_file" -d "$output_dir"
        return $?
    fi
}

# Tar/Tar.gz/Tar.bz2/Tar.xz 解压（带进度条）
tar_with_progress() {
    local archive_file="$1"
    local output_dir="$2"

    # 使用 Python 进行带进度条的解压（更可靠）
    if command -v python3 >/dev/null 2>&1 || command -v python >/dev/null 2>&1; then
        local python_cmd=$(command -v python3 >/dev/null 2>&1 && echo "python3" || echo "python")
        local bar_width=$(get_progress_bar_width)

        $python_cmd - "$archive_file" "$output_dir" "$bar_width" << 'PYEOF'
import tarfile
import sys
import os

archive_path = sys.argv[1]
output_dir = sys.argv[2]
bar_width = int(sys.argv[3])

_progress_called = False

def update_progress(extracted, total):
    global _progress_called
    percent = int(extracted * 100 / total) if total > 0 else 0
    filled = int(bar_width * extracted / total) if total > 0 else 0
    bar = '=' * filled + '-' * (bar_width - filled)

    if not _progress_called:
        print(f"\n正在解压: {extracted}/{total} 文件")
        print(f"[{bar}] {percent}%", end='', flush=True)
        _progress_called = True
    else:
        sys.stdout.write(f'\r[{bar}] {percent}% ({extracted}/{total})')
        sys.stdout.flush()

    if extracted == total:
        print()

try:
    with tarfile.open(archive_path, 'r:*') as tar:
        members = tar.getmembers()
        total = len(members)
        extracted = 0

        for member in members:
            tar.extract(member, output_dir)
            extracted += 1

            if extracted % 100 == 0 or extracted == total:
                update_progress(extracted, total)

    print("解压完成")
    sys.exit(0)
except Exception as e:
    print(f"\n解压失败: {e}", file=sys.stderr)
    sys.exit(1)
PYEOF
        return $?
    else
        # 没有 Python，使用普通解压
        echo -e "${YELLOW}Python 不可用，使用普通解压${NC}"
        tar -xf "$archive_file" -C "$output_dir"
        return $?
    fi
}

# 7z 解压（带进度条）
7z_with_progress() {
    local archive_file="$1"
    local output_dir="$2"

    # 7z 有内置进度，使用 -bsp1 启用进度输出
    7z x "$archive_file" -o"$output_dir" -bsp1 -y 2>&1 | while IFS= read -r line; do
        if [[ "$line" =~ ([0-9]+)% ]]; then
            local percent="${BASH_REMATCH[1]}"
            local bar_width=$(get_progress_bar_width)
            _progress_first_call=
            update_progress_bar_with_width "正在解压" "$percent%" "$percent" "$bar_width" ""
        fi
    done

    # 7z 返回最后一个管道的返回码，需要检查文件是否成功解压
    [ -f "$output_dir/bedrock_server" ] || [ -d "$output_dir" ]
    return $?
}

# 检测压缩包格式并解压（带进度条）
extract_with_progress() {
    local archive_file="$1"
    local output_dir="$2"

    # 确保输出目录存在
    mkdir -p "$output_dir"

    # 根据文件扩展名选择解压方式
    case "$archive_file" in
        *.zip)
            echo -e "${BLUE}检测到 ZIP 格式${NC}"
            unzip_with_progress "$archive_file" "$output_dir"
            ;;
        *.tar.gz|*.tgz|*.tar.bz2|*.tbz2|*.tar.xz|*.txz|*.tar)
            echo -e "${BLUE}检测到 TAR 格式${NC}"
            tar_with_progress "$archive_file" "$output_dir"
            ;;
        *.7z)
            echo -e "${BLUE}检测到 7z 格式${NC}"
            if command -v 7z >/dev/null 2>&1; then
                7z_with_progress "$archive_file" "$output_dir"
            else
                echo -e "${YELLOW}7z 未安装，使用普通解压${NC}"
                7z x "$archive_file" -o"$output_dir" -y 2>/dev/null
            fi
            ;;
        *.rar)
            echo -e "${BLUE}检测到 RAR 格式${NC}"
            if command -v unrar >/dev/null 2>&1; then
                unrar x "$archive_file" "$output_dir" -y
            else
                echo -e "${RED}错误: 需要安装 unrar${NC}"
                return 1
            fi
            ;;
        *.gz)
            echo -e "${BLUE}检测到 GZ 单文件${NC}"
            gunzip -k "$archive_file" -C "$output_dir"
            ;;
        *.xz)
            echo -e "${BLUE}检测到 XZ 单文件${NC}"
            xz -dk "$archive_file" -C "$output_dir"
            ;;
        *)
            echo -e "${YELLOW}未知格式，尝试自动检测${NC}"
            # 尝试自动检测
            if command -v file >/dev/null 2>&1; then
                local file_type=$(file -b "$archive_file")
                case "$file_type" in
                    *Zip*)
                        unzip_with_progress "$archive_file" "$output_dir"
                        ;;
                    *gzip*)
                        tar_with_progress "$archive_file" "$output_dir"
                        ;;
                    *bzip2*)
                        tar_with_progress "$archive_file" "$output_dir"
                        ;;
                    *XZ*)
                        tar_with_progress "$archive_file" "$output_dir"
                        ;;
                    *)
                        echo -e "${RED}错误: 不支持的压缩格式${NC}"
                        return 1
                        ;;
                esac
            else
                echo -e "${RED}错误: 不支持的压缩格式${NC}"
                return 1
            fi
            ;;
    esac
}

# 统一API下载核心

# 从API下载服务器核心
download_core_from_api() {
    local server_type=$1
    local mc_version=$2
    local server_dir=$3
    local server_name="${4:-}"  # 可选：服务器名称，用于保存核心文件名到配置

    # 检查版本号是否包含 "-" (如 spongevanilla 的 1.10.2-5.2.0-BETA)
    local download_url
    if [[ "$mc_version" == *"-"* ]]; then
        # 分割版本号: 从左边第一个 "-" 分割
        # 1.21.11-18.0.0-RC2528 -> minecraft_version=1.21.11, build_version=18.0.0-RC2528
        local minecraft_version="${mc_version%%-*}"
        local build_version="${mc_version#*-}"
        download_url="http://download.hycexit.xyz/api/v2/mc/download/$server_type/$minecraft_version/$build_version"
    else
        download_url="http://download.hycexit.xyz/api/v2/mc/download/$server_type/$mc_version"
    fi

    echo -e "${BLUE}正在从 API 下载 $server_type $mc_version ...${NC}"
    echo -e "${YELLOW}下载链接: $download_url${NC}"

    # 基岩版下载文件名
    local output_file="$server_dir/server.jar"
    if [ "$server_type" = "bedrock" ]; then
        # Bedrock 系统要求检查
        echo -e "${YELLOW}正在检查系统兼容性...${NC}"
        local system_arch=$(uname -m)
        local os_name=$(uname -s)

        if [ "$system_arch" != "x86_64" ] && [ "$system_arch" != "amd64" ]; then
            echo -e "${RED}错误: Bedrock 服务器仅支持 amd64 架构，当前系统架构: $system_arch${NC}"
            return 1
        fi

        # 检查 Ubuntu 版本
        if [ "$os_name" = "Linux" ]; then
            if [ -f /etc/os-release ]; then
                local os_id=$(grep "^ID=" /etc/os-release | cut -d= -f2 | tr -d '"')
                local version_id=$(grep "^VERSION_ID=" /etc/os-release | cut -d= -f2 | tr -d '"')

                if [ "$os_id" = "ubuntu" ]; then
                    # 提取主版本号
                    local major_version=$(echo "$version_id" | cut -d. -f1)
                    if [ "$major_version" -lt 22 ]; then
                        echo -e "${RED}错误: Bedrock 服务器需要 Ubuntu 22.04 或更高版本，当前版本: $version_id${NC}"
                        return 1
                    fi
                elif [ "$os_id" != "windows" ]; then
                    echo -e "${RED}错误: Bedrock 服务器仅支持 Windows 或 Ubuntu 22.04+，当前系统: $os_id${NC}"
                    return 1
                fi
            fi
        fi
        echo -e "${GREEN}系统兼容性检查通过${NC}"

        output_file="$server_dir/bedrock-server.zip"
    fi

    # 切换到服务器目录，使用原始文件名下载
    cd "$server_dir"

    if download_with_progress "$download_url" "$output_file" "正在下载" "$server_type 服务器..." "true"; then
        # 获取下载的实际文件名（jar 或 zip）
        local downloaded_file=$(ls -t *.jar *.zip 2>/dev/null | head -1)

        # 如果提供了服务器名称，保存核心文件名到配置
        if [ -n "$server_name" ] && [ -n "$downloaded_file" ]; then
            update_server_core_file "$server_name" "$downloaded_file"
        fi

        # 基岩版需要解压
        if [ "$server_type" = "bedrock" ]; then
            echo -e "${BLUE}正在解压 Bedrock 服务器...${NC}"
            # 找到下载的 zip 文件
            local zip_file=$(ls -t bedrock-*.zip 2>/dev/null | head -1)
            if [ -n "$zip_file" ] && [ -f "$zip_file" ]; then
                # 使用带进度条的解压
                if unzip_with_progress "$zip_file" "$server_dir"; then
                    rm -f "$zip_file"
                    chmod +x "$server_dir/bedrock_server"
                    if [ -f "$server_dir/bedrock_server" ] && [ -x "$server_dir/bedrock_server" ]; then
                        echo -e "${GREEN}Bedrock 服务器解压成功${NC}"
                        return 0
                    fi
                fi
                echo -e "${RED}错误: Bedrock 服务器文件验证失败${NC}"
                return 1
            else
                echo -e "${RED}错误: 未找到下载的 zip 文件${NC}"
                return 1
            fi
        fi
        return 0
    else
        echo -e "${RED}$server_type 服务器下载失败${NC}"
        return 1
    fi
}

# 获取API支持的核心列表
get_api_core_list() {
    local api_url="http://download.hycexit.xyz/api/v2/mc/corelist"
    curl -s --connect-timeout 30 "$api_url" 2>/dev/null
}

# 从API获取指定核心的版本列表
get_versions_from_api() {
    local server_type=$1
    local core_list=$(get_api_core_list)

    if [ -z "$core_list" ]; then
        return 1
    fi

    # 核心名称映射 (脚本名称 -> API名称)
    local api_core_name="$server_type"
    case "$server_type" in
        "spongeforge"|"sponge")
            api_core_name="spongeforge"
            ;;
        "spongeneo")
            api_core_name="spongeneo"
            ;;
        "spongevanilla")
            api_core_name="spongevanilla"
            ;;
    esac

    # 检查 API 是否支持这个核心
    local support_check=$(echo "$core_list" | jq -r ".corelist[] | select(.project == \"$api_core_name\") | .project" 2>/dev/null)

    if [ -z "$support_check" ]; then
        # API 不支持这个核心（比如 vanilla、forge、fabric 等）
        return 1
    fi

    # 获取版本列表
    local versions=$(echo "$core_list" | jq -r ".corelist[] | select(.project == \"$api_core_name\") | .versions[]" 2>/dev/null)

    if [ -z "$versions" ]; then
        return 1
    fi

    echo "$versions"
}

# 检查核心是否在API中支持
is_core_supported_by_api() {
    local server_type=$1
    local core_list=$(get_api_core_list)

    if [ -z "$core_list" ]; then
        return 1
    fi

    echo "$core_list" | jq -e ".corelist[] | select(.project == \"$server_type\")" > /dev/null 2>&1
}

# 下载服务器核心
download_server_core() {
    local server_type=$1
    local mc_version=$2
    local server_dir=$3
    local server_name="${4:-}"  # 可选：服务器名称

    # 隐藏图形界面
    clear
    echo -e "${BLUE}正在准备下载服务器核心...${NC}"

    # 检查版本兼容性
    if ! check_version_compatibility "$server_type" "$mc_version"; then
        echo -e "${RED}版本兼容性检查失败${NC}"
        return 1
    fi

    # 核心名称映射 (脚本内部名称 -> API名称)
    local api_core_name="$server_type"
    case "$server_type" in
        "spongeforge"|"sponge")
            api_core_name="spongeforge"
            ;;
        "spongeneo")
            api_core_name="spongeneo"
            ;;
        "spongevanilla")
            api_core_name="spongevanilla"
            ;;
    esac

    # 尝试使用API下载
    if is_core_supported_by_api "$api_core_name"; then
        echo -e "${CYAN}正在使用 API 下载核心...${NC}"
        if download_core_from_api "$api_core_name" "$mc_version" "$server_dir" "$server_name"; then
            local result=$?
            if [ $result -eq 0 ]; then
                echo -e "${GREEN}服务器核心下载完成${NC}"
                if validate_downloaded_core "$server_dir" "$server_type"; then
                    echo -e "${GREEN}服务器核心验证通过${NC}"
                    sleep 2
                    return 0
                else
                    echo -e "${RED}服务器核心验证失败${NC}"
                    sleep 2
                    return 1
                fi
            fi
        fi
        # API下载失败，尝试备用方法
        echo -e "${YELLOW}API下载失败，尝试备用下载方式...${NC}"
    fi

    # 备用下载方法
    case $server_type in
        "vanilla")
            download_vanilla_server "$mc_version" "$server_dir"
            ;;
        "paper"|"spigot"|"pufferfish"|"purpur"|"leaves"|"leaf")
            download_paper_family_server "$server_type" "$mc_version" "$server_dir"
            ;;
        "folia")
            download_folia_server "$mc_version" "$server_dir"
            ;;
        "forge")
            download_forge_server "$mc_version" "$server_dir"
            ;;
        "fabric")
            download_fabric_server "$mc_version" "$server_dir"
            ;;
        "quilt")
            download_quilt_server "$mc_version" "$server_dir"
            ;;
        "neoforged")
            download_neoforged_server "$mc_version" "$server_dir"
            ;;
        "mohist")
            download_mohist_server "$mc_version" "$server_dir"
            ;;
        "liteloader")
            download_liteloader_server "$mc_version" "$server_dir"
            ;;
        "spongeforge"|"sponge"|"spongeneo"|"spongevanilla")
            download_sponge_server "$mc_version" "$server_dir"
            ;;
        "bedrock")
            download_bedrock_server "$mc_version" "$server_dir"
            ;;
        "craftbukkit")
            download_craftbukkit_server "$mc_version" "$server_dir"
            ;;
        "nukkit")
            download_nukkit_server "$mc_version" "$server_dir"
            ;;
        *)
            echo -e "${RED}不支持的服务器类型: $server_type${NC}"
            return 1
            ;;
    esac
    
    local result=$?
    
    # 重新显示图形界面
    if [ $result -eq 0 ]; then
        echo -e "${GREEN}服务器核心下载完成${NC}"
        # 验证下载的文件
        if validate_downloaded_core "$server_dir" "$server_type"; then
            echo -e "${GREEN}服务器核心验证通过${NC}"
        else
            echo -e "${RED}服务器核心验证失败${NC}"
            return 1
        fi
        sleep 2
        return 0
    else
        echo -e "${RED}服务器核心下载失败${NC}"
        sleep 2
        return 1
    fi
}

# 检查版本兼容性
check_version_compatibility() {
    local server_type="$1"
    local version="$2"
    
    local major=$(echo "$version" | awk -F. '{print $1}')
    local minor=$(echo "$version" | awk -F. '{print $2}')
    
    echo -e "${YELLOW}检查 $server_type 对版本 $version 的兼容性...${NC}"
    
    # 各服务器核心的兼容性检查
    case "$server_type" in
        "vanilla")
            if [ "$major" -eq 1 ] && [ "$minor" -lt 0 ]; then
                echo -e "${RED}错误: Vanilla 不支持 1.0 以下版本${NC}"
                return 1
            fi
            ;;
        "paper"|"spigot"|"pufferfish"|"purpur"|"leaves"|"leaf")
            if [ "$major" -eq 1 ] && [ "$minor" -lt 8 ]; then
                echo -e "${RED}错误: $server_type 不支持 1.8 以下版本${NC}"
                return 1
            fi
            ;;
        "folia")
            if [ "$major" -eq 1 ] && [ "$minor" -lt 19 ]; then
                echo -e "${YELLOW}警告: Folia 对 1.19 以下版本支持有限${NC}"
                return 1
            fi
            
            if [ "$major" -eq 1 ] && [ "$minor" -lt 20 ]; then
                echo -e "${YELLOW}注意: 建议使用 1.20+ 版本以获得最佳多线程性能${NC}"
                return 1
            fi
            ;;
        "spigot")
            if [ "$major" -eq 1 ] && [ "$minor" -lt 4 ]; then
                echo -e "${RED}错误: Spigot 不支持 1.4 以下版本${NC}"
                return 1
            fi
            ;;
        "forge"|"neoforged")
            if [ "$major" -eq 1 ] && [ "$minor" -lt 6 ]; then
                echo -e "${RED}错误: $server_type 不支持 1.6 以下版本${NC}"
                return 1
            fi
            ;;
        "fabric"|"quilt")
            if [ "$major" -eq 1 ] && [ "$minor" -lt 14 ]; then
                echo -e "${RED}错误: $server_type 不支持 1.14 以下版本${NC}"
                return 1
            fi
            ;;
    esac
    
    echo -e "${GREEN}版本兼容性检查通过${NC}"
    return 0
}

# 验证下载的核心文件
validate_downloaded_core() {
    local server_dir="$1"
    local server_type="$2"

    # 使用 detect_server_jar 来找到实际的文件名
    local core_name=$(detect_server_jar "$server_dir")
    local core_file="$server_dir/$core_name"

    if [ "$server_type" = "bedrock" ]; then
        # 基岩版服务器验证
        core_file="$server_dir/bedrock_server"
    fi

    if [ ! -f "$core_file" ]; then
        echo -e "${RED}错误: 未找到服务器核心文件${NC}"
        echo -e "${YELLOW}期望路径: $core_file${NC}"
        echo -e "${YELLOW}目录内容: $(ls -la "$server_dir" | head -10)${NC}"
        return 1
    fi

    # 检查文件大小
    local file_size=$(stat -c%s "$core_file" 2>/dev/null || echo 0)
    if [ "$file_size" -lt 1000 ]; then  # 小于1KB可能是错误文件
        echo -e "${RED}错误: 服务器核心文件大小异常${NC}"
        return 1
    fi

    # 检查文件类型
    if [ "$server_type" != "bedrock" ]; then
        # Java服务器检查JAR文件
        local file_type=$(file -b "$core_file" 2>/dev/null | grep -i "jar\|zip" || echo "")
        if [ -z "$file_type" ]; then
            echo -e "${RED}警告: 文件可能不是有效的JAR文件${NC}"
            # 不直接返回错误，因为有些服务器核心可能是其他格式
        fi
    else
        # 基岩版服务器检查可执行文件
        local file_type=$(file -b "$core_file" 2>/dev/null | grep -i "executable\|binary" || echo "")
        if [ -z "$file_type" ]; then
            echo -e "${RED}警告: 文件可能不是有效的可执行文件${NC}"
        fi
    fi

    return 0
}

# 下载Vanilla服务器
download_vanilla_server() {
    local mc_version=$1
    local server_dir=$2
    
    echo -e "${BLUE}正在下载 Vanilla $mc_version ...${NC}"
    
    # 使用Mojang官方API获取下载信息
    local version_manifest_url="https://launchermeta.mojang.com/mc/game/version_manifest.json"
    local version_manifest=$(curl -s --connect-timeout 30 "$version_manifest_url")
    
    if [ -z "$version_manifest" ]; then
        echo -e "${RED}错误: 无法获取版本清单${NC}"
        return 1
    fi
    
    # 查找指定版本的下载信息
    local version_info_url=$(echo "$version_manifest" | jq -r ".versions[] | select(.id == \"$mc_version\") | .url")
    
    if [ -z "$version_info_url" ] || [ "$version_info_url" = "null" ]; then
        echo -e "${RED}错误: 找不到版本 $mc_version 的信息${NC}"
        return 1
    fi
    
    # 获取服务器JAR下载URL
    local version_info=$(curl -s --connect-timeout 30 "$version_info_url")
    local server_jar_url=$(echo "$version_info" | jq -r ".downloads.server.url")
    
    if [ -z "$server_jar_url" ] || [ "$server_jar_url" = "null" ]; then
        echo -e "${RED}错误: 无法获取服务器JAR下载URL${NC}"
        return 1
    fi
    
    # 下载服务器JAR
    echo -e "${BLUE}正在从官方服务器下载...${NC}"
    if download_with_progress "$server_jar_url" "$server_dir/server.jar" "正在下载" "Vanilla服务器..."; then
        return 0
    else
        echo -e "${RED}Vanilla 服务器下载失败${NC}"
        return 1
    fi
}

# 获取备用下载URL
get_backup_download_url() {
    local server_type=$1
    local mc_version=$2
    
    case "$server_type" in
        "paper"|"spigot")
            echo "https://download.hycexit.xyz/$server_type/$server_type-$mc_version.jar"
            ;;
        "pufferfish")
            echo "https://github.com/pufferfish-gg/Pufferfish/releases/download/$mc_version/pufferfish-server-$mc_version.jar"
            ;;
        "purpur")
            echo "https://api.purpurmc.org/v2/purpur/$mc_version/latest/download"
            ;;
        "forge")
            echo "https://files.minecraftforge.net/maven/net/minecraftforge/forge/$mc_version/forge-$mc_version-installer.jar"
            ;;
        "fabric")
            echo "https://meta.fabricmc.net/v2/versions/loader/$mc_version/server/jar"
            ;;
        "bedrock")
            case $ARCH in
                "amd64")
                    echo "https://minecraft.azureedge.net/bin-linux/bedrock-server-$mc_version.zip"
                    ;;
                "arm64")
                    echo "https://minecraft.azureedge.net/bin-linux-arm64/bedrock-server-$mc_version.zip"
                    ;;
                *)
                    echo ""
                    ;;
            esac
            ;;
        *)
            echo ""
            ;;
    esac
}

# 下载Paper系列服务器
download_paper_family_server() {
    local server_type=$1
    local mc_version=$2
    local server_dir=$3
    
    echo -e "${BLUE}正在下载 $server_type $mc_version ...${NC}"
    
    local download_url=""
    
    # 根据服务器类型选择下载源
    case "$server_type" in
        "paper")
            # PaperMC API v2
            local paper_api="https://api.papermc.io/v2/projects/paper"
            local builds_info=$(curl -s --connect-timeout 30 "$paper_api/versions/$mc_version/builds")
            if [ -z "$builds_info" ] || [ "$builds_info" = "null" ]; then
                echo -e "${RED}错误: 无法获取 Paper $mc_version 的构建信息${NC}"
                return 1
            fi
            local latest_build=$(echo "$builds_info" | jq -r '.builds[-1].build')
            download_url="$paper_api/versions/$mc_version/builds/$latest_build/downloads/paper-$mc_version-$latest_build.jar"
            ;;
        "spigot")
            # Spigot下载
            download_url="https://cdn.getbukkit.org/spigot/spigot-$mc_version.jar"
            ;;
        "pufferfish")
            # Pufferfish下载
            download_url="https://ci.pufferfish.host/job/Pufferfish-$mc_version/lastSuccessfulBuild/artifact/build/libs/pufferfish-server-$mc_version.jar"
            ;;
        "purpur")
            # Purpur下载
            local purpur_api="https://api.purpurmc.org/v2/purpur"
            local build_info=$(curl -s --connect-timeout 30 "$purpur_api/$mc_version")
            if [ -z "$build_info" ] || [ "$build_info" = "null" ]; then
                echo -e "${RED}错误: 无法获取 Purpur $mc_version 的构建信息${NC}"
                return 1
            fi
            local latest_build=$(echo "$build_info" | jq -r '.builds.latest')
            download_url="$purpur_api/$mc_version/$latest_build/download"
            ;;
        "leaves")
            # Leaves下载
            download_url="https://ci.2lstudios.dev/job/Leaves-$mc_version/lastSuccessfulBuild/artifact/leaves-server-$mc_version.jar"
            ;;
        "leaf")
            # Leaf下载
            download_url="https://ci.william278.net/job/Leaf-$mc_version/lastSuccessfulBuild/artifact/leaf-server-$mc_version.jar"
            ;;
    esac
    
    if [ -z "$download_url" ]; then
        echo -e "${RED}错误: 无法生成下载链接${NC}"
        return 1
    fi
    
    # 验证URL
    if ! validate_download_url "$download_url"; then
        echo -e "${YELLOW}警告: 主要下载URL无效，尝试备用方案...${NC}"
        download_url=$(get_backup_download_url "$server_type" "$mc_version")
        if [ -z "$download_url" ]; then
            echo -e "${RED}错误: 所有下载源都失败${NC}"
            return 1
        fi
    fi
    
    # 下载服务器JAR
    if download_with_progress "$download_url" "$server_dir/server.jar" "正在下载" "$server_type服务器..."; then
        # 验证下载的文件
        if validate_downloaded_core "$server_dir" "$server_type"; then
            echo -e "${GREEN}$server_type 服务器下载成功${NC}"
            return 0
        else
            echo -e "${RED}下载的文件验证失败${NC}"
            return 1
        fi
    else
        echo -e "${RED}$server_type 服务器下载失败${NC}"
        return 1
    fi
}

# 下载Folia服务器
download_folia_server() {
    local mc_version=$1
    local server_dir=$2
    
    echo -e "${BLUE}正在下载 Folia $mc_version ...${NC}"
    
    # Folia API
    local folia_api="https://api.papermc.io/v2/projects/folia"
    local builds_info=$(curl -s --connect-timeout 30 "$folia_api/versions/$mc_version/builds")
    
    if [ -z "$builds_info" ] || [ "$builds_info" = "null" ]; then
        echo -e "${RED}错误: 无法获取 Folia $mc_version 的构建信息${NC}"
        return 1
    fi
    
    local latest_build=$(echo "$builds_info" | jq -r '.builds[-1].build')
    local download_url="$folia_api/versions/$mc_version/builds/$latest_build/downloads/folia-$mc_version-$latest_build.jar"
    
    if download_with_progress "$download_url" "$server_dir/server.jar" "正在下载" "Folia服务器..."; then
        if validate_downloaded_core "$server_dir" "folia"; then
            echo -e "${GREEN}Folia 服务器下载成功${NC}"
            return 0
        else
            echo -e "${RED}下载的文件验证失败${NC}"
            return 1
        fi
    else
        echo -e "${RED}Folia 服务器下载失败${NC}"
        return 1
    fi
}

# 下载Forge服务器
download_forge_server() {
    local mc_version=$1
    local server_dir=$2
    
    echo -e "${BLUE}正在下载 Forge $mc_version ...${NC}"
    
    # 获取Forge版本信息
    local forge_versions_url="https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json"
    local forge_versions=$(curl -s --connect-timeout 30 "$forge_versions_url")
    
    if [ -z "$forge_versions" ] || [ "$forge_versions" = "null" ]; then
        echo -e "${RED}错误: 无法获取Forge版本信息${NC}"
        return 1
    fi
    
    # 获取推荐的Forge版本
    local forge_version=$(echo "$forge_versions" | jq -r ".promos[\"$mc_version-recommended\"] // .promos[\"$mc_version-latest\"]")
    
    if [ -z "$forge_version" ] || [ "$forge_version" = "null" ]; then
        echo -e "${RED}错误: 无法找到Forge版本 $mc_version${NC}"
        return 1
    fi
    
    # 构建下载URL
    local download_url="https://maven.minecraftforge.net/net/minecraftforge/forge/$mc_version-$forge_version/forge-$mc_version-$forge_version-installer.jar"
    
    echo -e "${BLUE}Forge版本: $forge_version${NC}"
    
    # 下载Forge安装器
    if download_with_progress "$download_url" "$server_dir/forge-installer.jar" "正在下载" "Forge安装器..."; then
        # 安装Forge服务器
        echo -e "${BLUE}正在安装Forge服务器...${NC}"
        cd "$server_dir"
        
        # 根据版本选择安装方式
        local major_version=$(echo "$mc_version" | awk -F. '{print $1}')
        local minor_version=$(echo "$mc_version" | awk -F. '{print $2}')
        
        if [ "$major_version" -eq 1 ] && [ "$minor_version" -ge 16 ]; then
            # 新版本安装方式
            java -jar forge-installer.jar --installServer
        else
            # 旧版本安装方式
            java -jar forge-installer.jar --installServer
        fi
        
        if [ $? -eq 0 ]; then
            # 清理安装器
            rm -f forge-installer.jar
            
            # 查找生成的服务器JAR文件
            local server_jar=$(find "$server_dir" -maxdepth 1 -name "forge-$mc_version-*.jar" | head -1)
            if [ -n "$server_jar" ] && [ -f "$server_jar" ]; then
                # 重命名为server.jar
                mv "$server_jar" "server.jar"
                echo -e "${GREEN}Forge 服务器安装成功${NC}"
                return 0
            else
                # 尝试其他可能的命名
                local alt_jars=(
                    "forge-$mc_version-$forge_version.jar"
                    "forge-$mc_version-$forge_version-universal.jar"
                    "minecraft_server.$mc_version.jar"
                )
                
                for jar in "${alt_jars[@]}"; do
                    if [ -f "$jar" ]; then
                        mv "$jar" "server.jar"
                        echo -e "${GREEN}Forge 服务器安装成功${NC}"
                        return 0
                    fi
                done
                
                echo -e "${RED}错误: 无法找到Forge服务器JAR文件${NC}"
                return 1
            fi
        else
            echo -e "${RED}Forge 安装失败${NC}"
            return 1
        fi
    else
        echo -e "${RED}Forge 安装器下载失败${NC}"
        return 1
    fi
}

# 下载Fabric服务器
download_fabric_server() {
    local mc_version=$1
    local server_dir=$2
    
    echo -e "${BLUE}正在下载 Fabric $mc_version ...${NC}"
    
    # Fabric安装器API
    local fabric_installer_url="https://meta.fabricmc.net/v2/versions/installer"
    local installer_info=$(curl -s --connect-timeout 30 "$fabric_installer_url")
    
    if [ -z "$installer_info" ] || [ "$installer_info" = "null" ]; then
        echo -e "${RED}错误: 无法获取Fabric安装器信息${NC}"
        return 1
    fi
    
    # 获取最新的安装器版本
    local installer_url=$(echo "$installer_info" | jq -r '.[0].url')
    
    if [ -z "$installer_url" ] || [ "$installer_url" = "null" ]; then
        echo -e "${RED}错误: 无法获取Fabric安装器URL${NC}"
        return 1
    fi
    
    # 下载Fabric安装器
    if download_with_progress "$installer_url" "$server_dir/fabric-installer.jar" "正在下载" "Fabric安装器..."; then
        # 安装Fabric服务器
        echo -e "${BLUE}正在安装Fabric服务器...${NC}"
        cd "$server_dir"
        
        # 安装Fabric服务器
        java -jar fabric-installer.jar server -mcversion "$mc_version" -downloadMinecraft
        
        if [ $? -eq 0 ]; then
            # 清理安装器
            rm -f fabric-installer.jar
            
            # 检查是否生成了服务器JAR
            if [ -f "fabric-server-launch.jar" ]; then
                # Fabric使用特殊的启动方式，需要保留fabric-server-launch.jar
                echo -e "${GREEN}Fabric 服务器安装成功${NC}"
                
                # 同时需要server.jar（原版服务器核心）
                if [ ! -f "server.jar" ]; then
                    echo -e "${YELLOW}警告: 未找到server.jar，可能需要手动下载${NC}"
                fi
                
                return 0
            else
                echo -e "${RED}错误: Fabric服务器安装不完整${NC}"
                return 1
            fi
        else
            echo -e "${RED}Fabric 安装失败${NC}"
            return 1
        fi
    else
        echo -e "${RED}Fabric 安装器下载失败${NC}"
        return 1
    fi
}

# 下载Quilt服务器
download_quilt_server() {
    local mc_version=$1
    local server_dir=$2
    
    echo -e "${BLUE}正在下载 Quilt $mc_version ...${NC}"
    
    # Quilt安装器
    local quilt_installer_url="https://maven.quiltmc.org/repository/release/org/quiltmc/quilt-installer/latest/quilt-installer-latest.jar"
    
    if download_with_progress "$quilt_installer_url" "$server_dir/quilt-installer.jar" "正在下载" "Quilt安装器..."; then
        # 安装Quilt服务器
        echo -e "${BLUE}正在安装Quilt服务器...${NC}"
        cd "$server_dir"
        java -jar quilt-installer.jar server "$mc_version" --download-server
        
        if [ $? -eq 0 ]; then
            rm -f quilt-installer.jar
            echo -e "${GREEN}Quilt 服务器安装成功${NC}"
            return 0
        else
            echo -e "${RED}Quilt 服务器安装失败${NC}"
            return 1
        fi
    else
        echo -e "${RED}Quilt 安装器下载失败${NC}"
        return 1
    fi
}

# 下载NeoForged服务器
download_neoforged_server() {
    local mc_version=$1
    local server_dir=$2
    
    echo -e "${BLUE}正在下载 NeoForged $mc_version ...${NC}"
    
    # NeoForged安装器
    local neoforged_installer_url="https://maven.neoforged.net/releases/net/neoforged/neoforged/$mc_version/neoforged-$mc_version-installer.jar"
    
    if download_with_progress "$neoforged_installer_url" "$server_dir/neoforged-installer.jar" "正在下载" "NeoForged安装器..."; then
        # 安装NeoForged服务器
        echo -e "${BLUE}正在安装NeoForged服务器...${NC}"
        cd "$server_dir"
        java -jar neoforged-installer.jar --installServer
        
        if [ $? -eq 0 ]; then
            rm -f neoforged-installer.jar
            echo -e "${GREEN}NeoForged 服务器安装成功${NC}"
            return 0
        else
            echo -e "${RED}NeoForged 服务器安装失败${NC}"
            return 1
        fi
    else
        echo -e "${RED}NeoForged 安装器下载失败${NC}"
        return 1
    fi
}

# 下载Mohist服务器
download_mohist_server() {
    local mc_version=$1
    local server_dir=$2
    
    echo -e "${BLUE}正在下载 MohistMC $mc_version ...${NC}"
    
    # MohistMC API
    local mohist_api="https://mohistmc.com/api/v2/projects/mohist"
    local build_info=$(curl -s --connect-timeout 30 "$mohist_api/$mc_version/builds")
    
    if [ -z "$build_info" ] || [ "$build_info" = "null" ]; then
        echo -e "${RED}错误: 无法获取MohistMC构建信息${NC}"
        return 1
    fi
    
    local latest_build=$(echo "$build_info" | jq -r '.builds[-1]')
    local download_url="$mohist_api/$mc_version/builds/$latest_build/download"
    
    if download_with_progress "$download_url" "$server_dir/server.jar" "正在下载" "MohistMC服务器..."; then
        echo -e "${GREEN}MohistMC 服务器下载成功${NC}"
        return 0
    else
        echo -e "${RED}MohistMC 服务器下载失败${NC}"
        return 1
    fi
}

# 下载LiteLoader服务器
download_liteloader_server() {
    local mc_version=$1
    local server_dir=$2
    
    echo -e "${BLUE}正在下载 LiteLoader $mc_version ...${NC}"
    
    # LiteLoader下载URL
    local download_url="http://dl.liteloader.com/versions/com/mumfrey/liteloader/$mc_version/liteloader-$mc_version-release.jar"
    
    if download_with_progress "$download_url" "$server_dir/server.jar" "正在下载" "LiteLoader服务器..."; then
        echo -e "${GREEN}LiteLoader 服务器下载成功${NC}"
        return 0
    else
        echo -e "${RED}LiteLoader 服务器下载失败${NC}"
        return 1
    fi
}

# 新增核心下载函数

# 下载CraftBukkit服务器
download_craftbukkit_server() {
    local mc_version=$1
    local server_dir=$2

    echo -e "${BLUE}正在下载 CraftBukkit $mc_version ...${NC}"

    # 尝试从API下载
    if download_core_from_api "craftbukkit" "$mc_version" "$server_dir"; then
        echo -e "${GREEN}CraftBukkit 服务器下载成功${NC}"
        return 0
    fi

    # 备用: 从 getbukkit.org 下载
    local download_url="https://getbukkit.org/download/craftbukkit"
    echo -e "${YELLOW}正在从备用服务器下载...${NC}"

    # 注意: CraftBukkit 官方不提供直接下载，使用 Spigot 作为替代
    echo -e "${RED}警告: CraftBukkit 官方已停止维护，建议使用 Spigot 或 Paper${NC}"
    return 1
}

# 下载Nukkit服务器
download_nukkit_server() {
    local mc_version=$1
    local server_dir=$2

    echo -e "${BLUE}正在下载 Nukkit $mc_version ...${NC}"

    # 尝试从API下载
    if download_core_from_api "nukkit" "$mc_version" "$server_dir"; then
        echo -e "${GREEN}Nukkit 服务器下载成功${NC}"
        return 0
    fi

    # 备用: 从 Nukkit 官方下载
    local download_url="https://ci.nukkitx.com/job/NukkitX/lastSuccessfulBuild/artifact/target/nukkit-1.0-all.jar"

    echo -e "${YELLOW}正在从备用服务器下载...${NC}"
    if download_with_progress "$download_url" "$server_dir/server.jar" "正在下载" "Nukkit服务器..."; then
        echo -e "${GREEN}Nukkit 服务器下载成功${NC}"
        return 0
    else
        echo -e "${RED}Nukkit 服务器下载失败${NC}"
        return 1
    fi
}

# 下载Sponge服务器
download_sponge_server() {
    local mc_version=$1
    local server_dir=$2
    
    echo -e "${BLUE}正在下载 Sponge $mc_version ...${NC}"
    
    # Sponge API
    local sponge_api="https://repo.spongepowered.org/repository/maven-releases/org/spongepowered/spongevanilla"
    local version_info=$(curl -s --connect-timeout 30 "$sponge_api/$mc_version")
    
    if [ -z "$version_info" ]; then
        echo -e "${RED}错误: 无法获取Sponge版本信息${NC}"
        return 1
    fi
    
    # 解析最新版本
    local latest_version=$(echo "$version_info" | grep -oP 'spongevanilla-\K[0-9\.]+' | head -1)
    local download_url="$sponge_api/$mc_version/spongevanilla-$mc_version-$latest_version.jar"
    
    if download_with_progress "$download_url" "$server_dir/server.jar" "正在下载" "Sponge服务器..."; then
        echo -e "${GREEN}Sponge 服务器下载成功${NC}"
        return 0
    else
        echo -e "${RED}Sponge 服务器下载失败${NC}"
        return 1
    fi
}

# 下载基岩版服务器
download_bedrock_server() {
    local mc_version=$1
    local server_dir=$2
    
    echo -e "${BLUE}正在下载 Bedrock 服务器 $mc_version ...${NC}"
    
    # 基岩版服务器下载URL模式
    local download_url=""
    
    # 根据架构确定下载链接
    case $ARCH in
        "amd64")
            download_url="https://www.minecraft.net/bedrockdedicatedserver/bin-linux/bedrock-server-$mc_version.zip"
            ;;
        "arm64")
            download_url="https://www.minecraft.net/bedrockdedicatedserver/bin-linux-arm64/bedrock-server-$mc_version.zip"
            ;;
        *)
            show_msg "错误" "不支持的架构: $ARCH"
            return 1
            ;;
    esac
    
    # 备用下载源
    local alt_urls=(
        "https://edll.scribeserver.com/bedrock/bedrock-server-$mc_version.zip"
        "http://download.hycexit.xyz/bedrock/bedrock-server-$mc_version.zip"
    )
    
    # 尝试下载
    local download_success=false
    for url in "$download_url" "${alt_urls[@]}"; do
        echo -e "${YELLOW}尝试下载: $url${NC}"
        if download_with_progress "$url" "$server_dir/bedrock-server.zip" "正在下载" "Bedrock服务器..."; then
            download_success=true
            break
        fi
    done
    
    if [ "$download_success" = false ]; then
        show_msg "错误" "所有下载源都失败"
        return 1
    fi
    
    # 解压文件（带进度条）
    echo -e "${BLUE}正在解压 Bedrock 服务器...${NC}"
    local zip_file="$server_dir/bedrock-server.zip"

    # 使用带进度条的解压
    if unzip_with_progress "$zip_file" "$server_dir"; then
        rm -f "$zip_file"
        chmod +x "$server_dir/bedrock_server"
        if [ -f "$server_dir/bedrock_server" ] && [ -x "$server_dir/bedrock_server" ]; then
            echo -e "${GREEN}Bedrock 服务器安装成功${NC}"
            return 0
        fi
    fi
    show_msg "错误" "Bedrock 服务器文件验证失败"
    return 1
}

# 服务器操作菜单
server_operations_menu() {
    local server_name="$1"

    # CLI 模式调用 CLI 版本
    if [ "$NO_GUI" = "true" ]; then
        cli_server_operations_menu "$server_name"
        return
    fi

    while true; do
        choice=$(safe_whiptail --nocancel --clear \
            --title "管理服务器: $server_name" \
            --menu "请选择操作：" 20 60 10 \
            "1" "启动服务器" \
            "2" "文件与配置" \
            "3" "删除服务器" \
            "0" "返回服务器列表" \
            3>&1 1>&2 2>&3)

        case $choice in
            1) start_server "$server_name" ;;
            2) manage_server_files "$server_name" ;;
            3) delete_server "$server_name" ; break ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 管理现有服务器
manage_existing_servers() {
    local preset_server="$1"
    
    # 如果指定了服务器名称，直接进入该服务器的管理
    if [ -n "$preset_server" ]; then
        if ! is_server_exists "$preset_server"; then
            show_msg "错误" "服务器 '$preset_server' 不存在"
            return
        fi
        
        # 直接进入服务器管理菜单
        server_operations_menu "$preset_server"
        return
    fi
    
    # 从配置文件获取服务器列表
    local servers=()
    if [ -f "$CONFIG_FILE" ]; then
        while IFS= read -r server; do
            local name=$(echo "$server" | jq -r '.name')
            local type=$(echo "$server" | jq -r '.type')
            local version=$(echo "$server" | jq -r '.version')
            servers+=("$name" "$type ($version)")
        done < <(jq -c '.servers[]' "$CONFIG_FILE")
    fi
    
    if [ ${#servers[@]} -eq 0 ]; then
        show_msg "信息" "没有可用的服务器"
        return
    fi

    # 选择服务器
    if [ "$NO_GUI" = "true" ]; then
        selected=$(cli_menu_select "选择要管理的服务器" "${servers[@]}")
    else
        selected=$(safe_whiptail --menu "选择要管理的服务器：" 20 60 10 "${servers[@]}" 3>&1 1>&2 2>&3)
    fi
    [ $? -ne 0 ] && return  
    
    if [ -z "$selected" ]; then
        return
    fi
    
    # 服务器操作菜单
    server_operations_menu "$selected"
}

# 服务器启动脚本创建和管理

# 创建启动脚本（适配所有核心类型，调用相应Java版本）
create_start_script() {
    local server_dir=$1
    local server_type=$2
    local mc_version=$3
    local jdk_version=$4

    echo -e "${BLUE}正在创建启动脚本...${NC}"

    # 从配置中获取核心文件名
    local server_name=$(basename "$server_dir")
    local core_file=""
    if [ -f "$CONFIG_FILE" ]; then
        core_file=$(jq -r --arg name "$server_name" '.servers[] | select(.name == $name) | .core_file // ""' "$CONFIG_FILE" 2>/dev/null)
    fi

    # 如果配置中没有，从服务器目录检测
    if [ -z "$core_file" ]; then
        core_file=$(ls -t "$server_dir"/*.jar 2>/dev/null | head -1)
        if [ -n "$core_file" ]; then
            core_file=$(basename "$core_file")
        fi
    fi

    # 保存核心文件名到服务器目录（供启动脚本读取）
    if [ -n "$core_file" ]; then
        echo "$core_file" > "$server_dir/.server_core"
    fi

    # 基岩版服务器不需要Java，使用不同的启动脚本
    if [ "$server_type" = "bedrock" ]; then
        create_bedrock_start_script "$server_dir"
        return $?
    fi

    # 获取合适的Java路径
    local java_path
    if [ -n "$jdk_version" ] && [ -d "$MCJDK_DIR/jdk$jdk_version" ]; then
        java_path="$MCJDK_DIR/jdk$jdk_version/bin/java"
    else
        # 自动检测合适的Java版本
        java_path=$(find_appropriate_java "$mc_version")
    fi
    
    # 验证Java路径
    if [ ! -f "$java_path" ] && ! command -v "$java_path" >/dev/null 2>&1; then
        # 获取服务器需要的JDK版本
        local required_jdk=$(get_required_jdk_version "$mc_version")

        # 尝试使用系统Java
        if command -v java >/dev/null 2>&1; then
            local system_java_version=$(java -version 2>&1 | head -1 | grep -o '[0-9._]*' | head -1)
            local system_major=$(echo "$system_java_version" | awk -F. '{print $1}')
            if [ "$system_major" -ge "$required_jdk" ]; then
                echo -e "${YELLOW}使用系统Java: $system_java_version${NC}"
                java_path="java"
            else
                echo -e "${YELLOW}系统Java版本 $system_java_version 不满足要求（需要JDK $required_jdk+）${NC}"
                # 询问用户是否安装JDK
                if ui_confirm "服务器需要JDK $required_jdk，但当前系统Java版本过低。\n\n是否自动安装JDK $required_jdk？"; then
                    if install_jdk_version "$required_jdk"; then
                        java_path="$MCJDK_DIR/jdk$required_jdk/bin/java"
                        echo -e "${GREEN}JDK $required_jdk 安装成功${NC}"
                    else
                        echo -e "${RED}JDK安装失败，将使用系统Java（可能无法正常运行）${NC}"
                        java_path="java"
                    fi
                else
                    echo -e "${YELLOW}用户取消安装，将使用系统Java${NC}"
                    java_path="java"
                fi
            fi
        else
            # 系统没有Java，询问用户是否安装
            echo -e "${YELLOW}未找到可用的Java环境${NC}"
            if ui_confirm "服务器需要JDK $required_jdk，但当前系统没有安装Java。\n\n是否自动安装JDK $required_jdk？"; then
                if install_jdk_version "$required_jdk"; then
                    java_path="$MCJDK_DIR/jdk$required_jdk/bin/java"
                    echo -e "${GREEN}JDK $required_jdk 安装成功${NC}"
                else
                    echo -e "${RED}错误: JDK安装失败，无法创建启动脚本${NC}"
                    return 1
                fi
            else
                echo -e "${RED}错误: 未安装Java，无法创建启动脚本${NC}"
                return 1
            fi
        fi
    fi
    
    # 根据服务器类型创建不同的启动脚本
    case "$server_type" in
        "vanilla"|"paper"|"spigot"|"pufferfish"|"purpur"|"leaves"|"leaf")
            create_vanilla_start_script "$server_dir" "$java_path" "$server_type" "$mc_version"
            ;;
        "folia")
            create_folia_start_script "$server_dir" "$java_path" "$server_type" "$mc_version"
            ;;
        "forge"|"neoforged")
            create_forge_start_script "$server_dir" "$java_path" "$mc_version"
            ;;
        "fabric"|"quilt")
            create_fabric_start_script "$server_dir" "$java_path" "$mc_version"
            ;;
        "mohist")
            create_mohist_start_script "$server_dir" "$java_path" "$server_type" "$mc_version"
            ;;
        "liteloader")
            create_liteloader_start_script "$server_dir" "$java_path" "$mc_version"
            ;;
        "sponge")
            create_sponge_start_script "$server_dir" "$java_path" "$mc_version"
            ;;
        *)
            # 默认使用通用启动脚本
            create_generic_start_script "$server_dir" "$java_path" "$server_type" "$mc_version"
            ;;
    esac
    
    local result=$?
    
    if [ $result -eq 0 ]; then
        # 保存Java版本信息到配置文件
        save_java_version_config "$server_dir" "$java_path" "$jdk_version"
        
        # 设置执行权限
        chmod +x "$server_dir/start.sh"

        echo -e "${GREEN}启动脚本创建完成${NC}"
        return 0
    else
        echo -e "${RED}启动脚本创建失败${NC}"
        return 1
    fi
}

# 保存Java版本配置
save_java_version_config() {
    local server_dir=$1
    local java_path=$2
    local jdk_version=$3
    
    cat > "$server_dir/java_version.cfg" << EOF
# Java版本配置
JAVA_PATH=$java_path
JDK_VERSION=$jdk_version
EOF
}

# 创建基岩版服务器启动脚本
create_bedrock_start_script() {
    local server_dir=$1

    cat > "$server_dir/start.sh" << 'EOF'
#!/bin/bash
# =====================================================
#   Minecraft Bedrock Edition 服务器启动脚本
#   类型: Bedrock Dedicated Server
#   无需Java环境，原生C++编写
# =====================================================

cd "$(dirname "$0")"

# 服务器信息
SERVER_NAME="$(basename "$(pwd)")"
SERVER_TYPE="bedrock"
START_TIME=$(date +"%Y-%m-%d %H:%M:%S")

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_message() {
    echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a server.log
}

# 检查服务器文件
check_server_files() {
    if [ ! -f "bedrock_server" ]; then
        log_message "${RED}错误: 未找到 bedrock_server 可执行文件${NC}"
        return 1
    fi

    # 检查执行权限
    if [ ! -x "bedrock_server" ]; then
        log_message "${YELLOW}设置执行权限...${NC}"
        chmod +x bedrock_server
        if [ $? -ne 0 ]; then
            log_message "${RED}错误: 无法设置执行权限${NC}"
            return 1
        fi
    fi

    # 检查必要的配置文件
    if [ ! -f "server.properties" ]; then
        log_message "${YELLOW}警告: 未找到 server.properties，将使用默认配置${NC}"
    fi

    if [ ! -f "permissions.json" ]; then
        log_message "${YELLOW}警告: 未找到 permissions.json，将使用默认权限${NC}"
    fi

    return 0
}

# 检查是否已运行
check_if_running() {
    if pgrep -f "bedrock_server" > /dev/null; then
        log_message "${RED}错误: Bedrock 服务器已在运行中${NC}"

        # 获取进程信息
        local pids=$(pgrep -f "bedrock_server")
        log_message "${YELLOW}运行的进程PID: $pids${NC}"

        # 询问是否强制停止
        read -t 10 -p "是否强制停止现有进程并启动新服务器? (y/N): " choice
        case "$choice" in
            y|Y)
                log_message "${YELLOW}正在停止现有进程...${NC}"
                pkill -f "bedrock_server"
                sleep 2
                # 再次检查
                if pgrep -f "bedrock_server" > /dev/null; then
                    log_message "${RED}无法停止现有进程，请手动处理${NC}"
                    return 1
                fi
                ;;
            *)
                log_message "${YELLOW}已取消启动${NC}"
                return 1
                ;;
        esac
    fi
    return 0
}

# 显示启动信息
show_startup_info() {
    echo "=========================================="
    echo "   Minecraft Bedrock 服务器启动"
    echo "=========================================="
    echo "服务器名称: $SERVER_NAME"
    echo "服务器类型: $SERVER_TYPE"
    echo "启动时间: $START_TIME"
    echo "工作目录: $(pwd)"
    echo "系统架构: $(uname -m)"
    echo "=========================================="

    # 显示服务器配置信息
    if [ -f "server.properties" ]; then
        echo "服务器配置:"
        echo "  - 端口: $(grep 'server-port=' server.properties | cut -d= -f2 2>/dev/null || echo "19132")"
        echo "  - 最大玩家: $(grep 'max-players=' server.properties | cut -d= -f2 2>/dev/null || echo "10")"
        echo "  - 游戏模式: $(grep 'gamemode=' server.properties | cut -d= -f2 2>/dev/null || echo "survival")"
        echo "  - 难度: $(grep 'difficulty=' server.properties | cut -d= -f2 2>/dev/null || echo "easy")"
    fi
    echo "=========================================="
}

# 信号处理函数
setup_signal_handlers() {
    trap 'handle_shutdown' INT TERM
    log_message "${BLUE}已设置信号处理${NC}"
}

# 关闭处理函数
handle_shutdown() {
    log_message "${YELLOW}收到关闭信号，正在停止服务器...${NC}"

    # 如果服务器仍在运行，强制终止
    if [ -n "$SERVER_PID" ] && kill -0 "$SERVER_PID" 2>/dev/null; then
        log_message "${YELLOW}服务器未正常关闭，强制终止...${NC}"
        kill -9 "$SERVER_PID" 2>/dev/null
    fi

    cleanup
    exit 0
}

# 清理函数
cleanup() {
    # 记录关闭时间
    local end_time=$(date +"%Y-%m-%d %H:%M:%S")
    log_message "${GREEN}服务器已停止于: $end_time${NC}"
    echo "=========================================="
}

# 等待服务器启动
wait_for_server_start() {
    local max_wait=30
    local wait_time=0

    log_message "${BLUE}等待服务器启动...${NC}"

    while [ $wait_time -lt $max_wait ]; do
        if [ -f "server.log" ] && grep -q "Server started" server.log 2>/dev/null; then
            log_message "${GREEN}服务器启动成功!${NC}"
            return 0
        fi

        # 检查进程是否存活
        if ! kill -0 "$SERVER_PID" 2>/dev/null; then
            log_message "${RED}服务器进程异常退出${NC}"
            return 1
        fi

        sleep 1
        ((wait_time++))
    done

    log_message "${YELLOW}警告: 服务器启动超时，但进程仍在运行${NC}"
    return 0
}

# 监控服务器状态
monitor_server() {
    local last_activity=$(date +%s)
    local inactivity_timeout=300  # 5分钟无活动超时

    log_message "${BLUE}开始监控服务器状态...${NC}"

    while true; do
        # 检查服务器进程是否存活
        if ! kill -0 "$SERVER_PID" 2>/dev/null; then
            log_message "${RED}服务器进程已停止${NC}"
            break
        fi

        # 检查服务器日志是否有新活动
        local current_time=$(date +%s)
        local log_mtime=$(stat -c %Y server.log 2>/dev/null || echo 0)

        if [ $((current_time - log_mtime)) -gt $inactivity_timeout ]; then
            log_message "${YELLOW}警告: 服务器无活动超过 $inactivity_timeout 秒${NC}"
        fi

        # 检查内存使用
        if command -v pmap >/dev/null 2>&1; then
            local memory_kb=$(pmap -x "$SERVER_PID" 2>/dev/null | tail -1 | awk '{print $3}')
            local memory_mb=$((memory_kb / 1024))

            if [ $memory_mb -gt 2048 ]; then  # 超过2GB警告
                log_message "${YELLOW}内存使用: ${memory_mb}MB (较高)${NC}"
            fi
        fi

        sleep 10
    done
}

# 主启动函数
main() {
    # 切换到脚本所在目录
    cd "$(dirname "$0")"

    # 创建日志文件
    touch server.log

    log_message "${BLUE}开始启动 Bedrock 服务器...${NC}"

    # 检查服务器文件
    if ! check_server_files; then
        log_message "${RED}服务器文件检查失败${NC}"
        exit 1
    fi

    # 检查是否已运行
    if ! check_if_running; then
        exit 1
    fi

    # 显示启动信息
    show_startup_info

    # 设置信号处理
    setup_signal_handlers

    # 启动服务器 - 使用 exec 替换进程，保持终端连接
    log_message "${GREEN}启动 Bedrock 服务器进程...${NC}"

    # 直接运行服务器，exec 会替换当前进程
    # 这样所有终端输入都会直接传递给服务器
    exec ./bedrock_server
}

# 脚本入口
if [ "$1" = "stop" ]; then
    # 停止服务器模式
    if [ -f "server.pid" ]; then
        PID=$(cat server.pid)
        if kill -0 "$PID" 2>/dev/null; then
            echo "正在停止服务器 (PID: $PID)..."
            kill "$PID"
            sleep 5
            if kill -0 "$PID" 2>/dev/null; then
                kill -9 "$PID"
            fi
            rm -f server.pid
            echo "服务器已停止"
        else
            echo "服务器未运行"
            rm -f server.pid
        fi
    else
        echo "未找到 server.pid 文件"
    fi
    exit 0
elif [ "$1" = "status" ]; then
    # 状态检查模式
    if [ -f "server.pid" ]; then
        PID=$(cat server.pid)
        if kill -0 "$PID" 2>/dev/null; then
            echo "服务器运行中 (PID: $PID)"
        else
            echo "服务器未运行"
            rm -f server.pid
        fi
    else
        echo "服务器未运行"
    fi
    exit 0
elif [ "$1" = "restart" ]; then
    # 重启模式
    if [ -f "server.pid" ]; then
        PID=$(cat server.pid)
        if kill -0 "$PID" 2>/dev/null; then
            echo "正在停止服务器..."
            kill "$PID"
            sleep 5
        fi
        rm -f server.pid
    fi
    # 继续启动
fi

# 启动服务器
main "$@"
EOF
}

# 创建原版/插件服务器启动脚本
create_vanilla_start_script() {
    local server_dir=$1
    local java_path=$2
    local server_type=$3
    local mc_version=$4
    
    # 检测服务器核心文件
    local server_jar=$(detect_server_jar "$server_dir")
    if [ -z "$server_jar" ]; then
        server_jar="server.jar"
    fi
    
    cat > "$server_dir/start.sh" << EOF
#!/bin/bash
# Minecraft服务器启动脚本
# 类型: $server_type
# 版本: $mc_version
# Java: $java_path

cd "\$(dirname "\$0")"

# 读取保存的核心文件名（如果存在）
if [ -f ".server_core" ]; then
    SERVER_JAR=\$(cat ".server_core")
fi

# 如果没有保存的文件名，则动态检测
if [ -z "\$SERVER_JAR" ]; then
    SERVER_JAR=\$(find . -maxdepth 1 -name "*.jar" ! -name "*-installer.jar" ! -name "*.log" ! -name "*.txt" | head -1)
fi

# 验证核心文件存在
if [ -z "\$SERVER_JAR" ] || [ ! -f "\$SERVER_JAR" ]; then
    echo -e "\033[31m错误: 未找到服务器核心文件\033[0m"
    exit 1
fi

# 加载Java配置
if [ -f "java_version.cfg" ]; then
    source "java_version.cfg"
fi

# 验证Java
if [ ! -f "\$JAVA_PATH" ] && ! command -v "\$JAVA_PATH" >/dev/null 2>&1; then
    echo -e "\033[33m警告: Java路径 \$JAVA_PATH 不可用，尝试使用系统Java\033[0m"
    if command -v java >/dev/null 2>&1; then
        JAVA_PATH="java"
    else
        echo -e "\033[31m错误: 未找到可用的Java环境\033[0m"
        exit 1
    fi
fi

# 基本JVM参数
JVM_OPTS="-Xms2G -Xmx4G -Djava.awt.headless=true -XX:+UseG1GC"
JVM_OPTS="\$JVM_OPTS -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=20"
JVM_OPTS="\$JVM_OPTS -XX:G1ReservePercent=20 -XX:MaxGCPauseMillis=50"
JVM_OPTS="\$JVM_OPTS -XX:G1HeapRegionSize=32M"

# 使用自定义日志配置（简化输出）
JVM_OPTS="\$JVM_OPTS -Dlog4j.configurationFile=log4j2.xml"

# 服务器特定优化
case "$server_type" in
    "paper"|"pufferfish"|"purpur"|"leaves"|"leaf")
        JVM_OPTS="\$JVM_OPTS -Dpaper.disableChannelLimits=true"
        JVM_OPTS="\$JVM_OPTS -Dpaper.playerconnection.keepalive=120"
        ;;
    "vanilla")
        JVM_OPTS="\$JVM_OPTS -Dcom.mojang.eula.agree=true"
        ;;
    "spigot")
        JVM_OPTS="\$JVM_OPTS -Dspigot.settings.bungeecord=false"
        ;;
esac

# 版本特定优化
case "$mc_version" in
    1.17*|1.18*|1.19*|1.20*|1.21*)
        JVM_OPTS="\$JVM_OPTS -XX:+UseG1GC -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40"
        ;;
    *)
        JVM_OPTS="\$JVM_OPTS -XX:+UseG1GC"
        ;;
esac

# 显示启动信息
echo "=========================================="
echo "启动 $server_type 服务器 $mc_version"
echo "Java: \$(\$JAVA_PATH -version 2>&1 | head -1)"
echo "核心文件: \$SERVER_JAR"
echo "内存: 2G-4G"
echo "=========================================="

# 启动服务器
\$JAVA_PATH \$JVM_OPTS -jar "\$SERVER_JAR" nogui

# 服务器退出处理
echo "=========================================="
echo "服务器已停止，返回管理器 - 退出代码: \$?"
echo "=========================================="
EOF
}

# 创建Forge服务器启动脚本
create_forge_start_script() {
    local server_dir=$1
    local java_path=$2
    local server_jar=$3
    
    # 检查Forge是否有自己的启动器
    if [ -f "$server_dir/run.sh" ] || [ -f "$server_dir/start.sh" ]; then
        # 如果Forge有自己的启动脚本，修改其中的Java路径
        local forge_script=$(find "$server_dir" -maxdepth 1 -name "run.sh" -o -name "start.sh" | head -1)
        if [ -n "$forge_script" ]; then
            # 备份原脚本
            cp "$forge_script" "$forge_script.backup"
            
            # 修改Java路径
            sed -i "s|java|$java_path|g" "$forge_script"
            sed -i "s|/.*/java|$java_path|g" "$forge_script"
            
            cp "$forge_script" "$server_dir/start.sh"
            echo -e "${YELLOW}使用Forge自带的启动脚本，已更新Java路径${NC}"
            return
        fi
    fi
    
    # 检查libraries目录是否存在（Forge特征）
    if [ -d "$server_dir/libraries" ]; then
        # 使用Forge的类路径启动
        cat > "$server_dir/start.sh" << EOF
#!/bin/bash
# Forge服务器启动脚本
# Java路径: $java_path
# 核心文件: $server_jar

cd "\$(dirname "\$0")"

# 读取保存的核心文件名（如果存在）
if [ -f ".server_core" ]; then
    SERVER_JAR=\$(cat ".server_core")
fi

# 如果没有保存的文件名，则动态检测
if [ -z "\$SERVER_JAR" ]; then
    SERVER_JAR=\$(find . -maxdepth 1 -name "*.jar" ! -name "*-installer.jar" ! -name "*.log" ! -name "*.txt" | head -1)
fi

# 验证核心文件存在
if [ -z "\$SERVER_JAR" ] || [ ! -f "\$SERVER_JAR" ]; then
    echo -e "\033[31m错误: 未找到服务器核心文件\033[0m"
    exit 1
fi

# 加载Java版本配置
if [ -f "java_version.cfg" ]; then
    source "java_version.cfg"
fi

# 验证Java路径
if [ ! -f "\$JAVA_PATH" ] && ! command -v "\$JAVA_PATH" >/dev/null 2>&1; then
    echo -e "\033[33m警告: Java路径 \$JAVA_PATH 不可用，尝试使用系统Java\033[0m"
    if command -v java >/dev/null 2>&1; then
        JAVA_PATH="java"
    else
        echo -e "\033[31m错误: 未找到可用的Java环境\033[0m"
        exit 1
    fi
fi

# Forge特定的JVM参数
JVM_OPTS="-Xms2G -Xmx4G -Djava.awt.headless=true -XX:+UseG1GC"
JVM_OPTS="\$JVM_OPTS -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=20"
JVM_OPTS="\$JVM_OPTS -XX:G1ReservePercent=20 -XX:MaxGCPauseMillis=50"
JVM_OPTS="\$JVM_OPTS -Dlog4j.configurationFile=log4j2.xml"

# 构建类路径
if [ -d "libraries" ]; then
    LIBRARIES=\$(find libraries -name "*.jar" 2>/dev/null | tr '\n' ':')
else
    LIBRARIES=""
fi

if [ -d "mods" ]; then
    MODS=\$(find mods -name "*.jar" 2>/dev/null | tr '\n' ':')
else
    MODS=""
fi

CLASSPATH="\$LIBRARIES\$MODS\$SERVER_JAR"

# 显示启动信息
echo "=========================================="
echo "正在启动 Forge 服务器"
echo "Java版本: \$(\$JAVA_PATH -version 2>&1 | head -1)"
echo "核心文件: \$SERVER_JAR"
echo "内存分配: 2G-4G"
echo "=========================================="

# 启动Forge服务器
\$JAVA_PATH \$JVM_OPTS -cp "\$CLASSPATH" net.minecraft.server.Main nogui

# 服务器退出处理
echo "=========================================="
echo "服务器已停止"
echo "退出代码: \$?"
echo "=========================================="
EOF
    else
        # 普通Forge启动
        cat > "$server_dir/start.sh" << EOF
#!/bin/bash
# Forge服务器启动脚本
# Java路径: $java_path
# 核心文件: $server_jar

cd "\$(dirname "\$0")"

# 读取保存的核心文件名（如果存在）
if [ -f ".server_core" ]; then
    SERVER_JAR=\$(cat ".server_core")
fi

# 如果没有保存的文件名，则动态检测
if [ -z "\$SERVER_JAR" ]; then
    SERVER_JAR=\$(find . -maxdepth 1 -name "*.jar" ! -name "*-installer.jar" ! -name "*.log" ! -name "*.txt" | head -1)
fi

# 验证核心文件存在
if [ -z "\$SERVER_JAR" ] || [ ! -f "\$SERVER_JAR" ]; then
    echo -e "\033[31m错误: 未找到服务器核心文件\033[0m"
    exit 1
fi

# 加载Java版本配置
if [ -f "java_version.cfg" ]; then
    source "java_version.cfg"
fi

# 验证Java路径
if [ ! -f "\$JAVA_PATH" ] && ! command -v "\$JAVA_PATH" >/dev/null 2>&1; then
    echo -e "\033[33m警告: Java路径 \$JAVA_PATH 不可用，尝试使用系统Java\033[0m"
    if command -v java >/dev/null 2>&1; then
        JAVA_PATH="java"
    else
        echo -e "\033[31m错误: 未找到可用的Java环境\033[0m"
        exit 1
    fi
fi

# JVM参数
JVM_OPTS="-Xms2G -Xmx4G -Djava.awt.headless=true -XX:+UseG1GC"
JVM_OPTS="\$JVM_OPTS -XX:+UnlockExperimentalVMOptions"
JVM_OPTS="\$JVM_OPTS -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20"
JVM_OPTS="\$JVM_OPTS -Dlog4j.configurationFile=log4j2.xml"

# 显示启动信息
echo "=========================================="
echo "正在启动 Forge 服务器"
echo "Java版本: \$(\$JAVA_PATH -version 2>&1 | head -1)"
echo "核心文件: \$SERVER_JAR"
echo "内存分配: 2G-4G"
echo "=========================================="

# 启动服务器
\$JAVA_PATH \$JVM_OPTS -jar "\$SERVER_JAR" nogui

# 服务器退出处理
echo "=========================================="
echo "服务器已停止"
echo "退出代码: \$?"
echo "=========================================="
EOF
    fi
}

# 创建Fabric服务器启动脚本
create_fabric_start_script() {
    local server_dir=$1
    local java_path=$2
    local server_jar=$3
    
    # 检查Fabric是否有自己的启动器
    if [ -f "$server_dir/fabric-server-launch.jar" ] || [ -f "$server_dir/fabric-server-*.jar" ]; then
        # Fabric使用特殊的启动方式
        cat > "$server_dir/start.sh" << EOF
#!/bin/bash
# Fabric服务器启动脚本
# Java路径: $java_path

cd "\$(dirname "\$0")"

# 读取保存的核心文件名（如果存在）
if [ -f ".server_core" ]; then
    SERVER_JAR=\$(cat ".server_core")
fi

# 如果没有保存的文件名，则动态检测
if [ -z "\$SERVER_JAR" ]; then
    SERVER_JAR=\$(find . -maxdepth 1 -name "*.jar" ! -name "*-installer.jar" ! -name "*.log" ! -name "*.txt" | head -1)
fi

# 验证核心文件存在
if [ -z "\$SERVER_JAR" ] || [ ! -f "\$SERVER_JAR" ]; then
    echo -e "\033[31m错误: 未找到服务器核心文件\033[0m"
    exit 1
fi

# 加载Java版本配置
if [ -f "java_version.cfg" ]; then
    source "java_version.cfg"
fi

# 验证Java路径
if [ ! -f "\$JAVA_PATH" ] && ! command -v "\$JAVA_PATH" >/dev/null 2>&1; then
    echo -e "\033[33m警告: Java路径 \$JAVA_PATH 不可用，尝试使用系统Java\033[0m"
    if command -v java >/dev/null 2>&1; then
        JAVA_PATH="java"
    else
        echo -e "\033[31m错误: 未找到可用的Java环境\033[0m"
        exit 1
    fi
fi

# JVM参数
JVM_OPTS="-Xms2G -Xmx4G -Djava.awt.headless=true -XX:+UseG1GC"
JVM_OPTS="\$JVM_OPTS -XX:+UnlockExperimentalVMOptions"
JVM_OPTS="\$JVM_OPTS -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20"

# Fabric启动参数
JVM_OPTS="\$JVM_OPTS -Dfabric.dli.config=config.json"

# 显示启动信息
echo "=========================================="
echo "正在启动 Fabric 服务器"
echo "Java版本: \$(\$JAVA_PATH -version 2>&1 | head -1)"
echo "核心文件: \$SERVER_JAR"
echo "内存分配: 2G-4G"
echo "=========================================="

# 启动Fabric服务器
\$JAVA_PATH \$JVM_OPTS -jar "\$SERVER_JAR" nogui

# 服务器退出处理
echo "=========================================="
echo "服务器已停止"
echo "退出代码: \$?"
echo "=========================================="
EOF
    else
        # 普通启动
        create_vanilla_start_script "$server_dir" "$java_path" "$server_jar" "fabric"
    fi
}

# 创建Folia服务器启动脚本
create_folia_start_script() {
    local server_dir=$1
    local java_path=$2
    local server_type=$3
    local mc_version=$4
    
    echo -e "${BLUE}正在创建Folia启动脚本...${NC}"
    
    # 检测服务器核心文件
    local server_jar=$(detect_server_jar "$server_dir")
    if [ -z "$server_jar" ]; then
        server_jar="server.jar"
    fi
    
    cat > "$server_dir/start.sh" << EOF
#!/bin/bash
# Folia多线程服务器启动脚本
# 类型: $server_type
# 版本: $mc_version
# Java: $java_path

cd "\$(dirname "\$0")"

# 读取保存的核心文件名（如果存在）
if [ -f ".server_core" ]; then
    SERVER_JAR=\$(cat ".server_core")
fi

# 如果没有保存的文件名，则动态检测
if [ -z "\$SERVER_JAR" ]; then
    SERVER_JAR=\$(find . -maxdepth 1 -name "*.jar" ! -name "*-installer.jar" ! -name "*.log" ! -name "*.txt" | head -1)
fi

# 验证核心文件存在
if [ -z "\$SERVER_JAR" ] || [ ! -f "\$SERVER_JAR" ]; then
    echo -e "\033[31m错误: 未找到服务器核心文件\033[0m"
    exit 1
fi

# 加载Java配置
if [ -f "java_version.cfg" ]; then
    source "java_version.cfg"
fi

# 验证Java
if [ ! -f "\$JAVA_PATH" ] && ! command -v "\$JAVA_PATH" >/dev/null 2>&1; then
    echo -e "\033[33m警告: Java路径不可用，尝试自动查找...\033[0m"
    JAVA_PATH=\$(which java 2>/dev/null || echo "java")
    if ! command -v "\$JAVA_PATH" >/dev/null 2>&1; then
        echo -e "\033[31m错误: 未找到Java环境\033[0m"
        exit 1
    fi
fi

# Folia特定的JVM参数 - 针对多线程优化
JVM_OPTS="-Xms2G -Xmx4G -Djava.awt.headless=true -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions"
JVM_OPTS="\$JVM_OPTS -XX:G1NewSizePercent=30 -XX:G1ReservePercent=15"
JVM_OPTS="\$JVM_OPTS -XX:MaxGCPauseMillis=30 -XX:G1HeapRegionSize=32M"

# Folia多线程优化参数
JVM_OPTS="\$JVM_OPTS -Dfolia.enable=true"
JVM_OPTS="\$JVM_OPTS -Dfolia.region-size=32"
JVM_OPTS="\$JVM_OPTS -Dfolia.max-chunk-gen-threads=3"

# 根据版本调整参数
case "$mc_version" in
    1.21*|1.20*)
        JVM_OPTS="\$JVM_OPTS -Dfolia.use-chunk-system=true"
        JVM_OPTS="\$JVM_OPTS -Dfolia.max-chunk-load-threads=4"
        ;;
    *)
        JVM_OPTS="\$JVM_OPTS -Dfolia.max-chunk-load-threads=3"
        ;;
esac

# 内存优化
JVM_OPTS="\$JVM_OPTS -Dfolia.max-tick-time=50"
JVM_OPTS="\$JVM_OPTS -Dfolia.tick-threads=2"

# 显示启动信息
echo "=========================================="
echo "启动 Folia 多线程服务器 $mc_version"
echo "Java: \$(\$JAVA_PATH -version 2>&1 | head -1)"
echo "核心文件: \$SERVER_JAR"
echo "内存: 2G-4G (多线程优化)"
echo "线程: 区域系统启用"
echo "=========================================="

# 启动Folia服务器
\$JAVA_PATH \$JVM_OPTS -jar "\$SERVER_JAR" nogui

# 服务器退出处理
echo "=========================================="
echo "Folia服务器已停止，返回管理器 - 退出代码: \$?"
echo "=========================================="
EOF

    # 创建Folia特定的配置文件
    generate_folia_config "$server_dir" "$mc_version"
}

# 生成Folia配置文件
generate_folia_config() {
    local server_dir=$1
    local mc_version=$2
    
    # 创建Folia配置文件目录
    mkdir -p "$server_dir/config"
    
    # 生成Folia配置文件
    cat > "$server_dir/config/paper-global.yml" << 'EOF'
# Folia 全局配置
# 这是Folia多线程服务器的配置文件

settings:
  # 区域设置
  region-size: 32
  # 最大区块生成线程数
  max-chunk-gen-threads: 3
  # 最大区块加载线程数
  max-chunk-load-threads: 4
  # 使用新的区块系统（1.20.5+）
  use-chunk-system: true
  
  # 线程设置
  tick-threads: 2
  # 最大tick时间（毫秒）
  max-tick-time: 50
  
  # 性能优化
  prevent-moving-into-unloaded-chunks: true
  enable-sync-chunk-writes: true
  
  # 实体优化
  max-entity-collisions: 8
  armor-stands-tick: true
  
  # 红石优化
  update-pathfinding-on-block-update: true
  fix-climbing-bypassing-cramming-rule: true

# 世界设置
world-settings:
  default:
    # 实体激活范围
    entity-activation-range:
      animals: 16
      monsters: 24
      raiders: 48
      misc: 8
      water: 8
      villagers: 16
      flying-monsters: 16
      
    # 实体每tick限制
    entities:
      entity-tracking-range:
        players: 48
        animals: 48
        monsters: 48
        misc: 32
        other: 64
      
      # 每tick处理的实体数量限制
      max-entity-collisions: 4
      tick-inactive-villagers: true
      
    # 孢子优化
    spawner:
      spawner-merged-radius: 4
      
    # 掉落物优化
    item:
      merge-radius: 2.5
      delay:
        player: 20
        general: 40
        
    # 动物优化
    animal:
      breeding-cooldown-seconds: 60
      
    # 怪物优化  
    monster:
      spawn-limits:
        monsters: 50
        animals: 10
        water-animals: 5
        ambient: 5
        water-ambient: 5
        axolotls: 5
EOF

    # 根据版本调整配置
    if [[ "$mc_version" == 1.21* ]]; then
        cat >> "$server_dir/config/paper-global.yml" << 'EOF'
    # 1.21+ 特定优化
    feature-versions:
      world-version: 15
      # 启用试验性功能
      enabled: true
EOF
    fi

    echo -e "${GREEN}Folia配置文件已生成${NC}"
}

# 创建MohistMC服务器启动脚本
create_mohist_start_script() {
    local server_dir=$1
    local java_path=$2
    local server_type=$3
    local mc_version=$4
    
    # 检测服务器核心文件
    local server_jar=$(detect_server_jar "$server_dir")
    if [ -z "$server_jar" ]; then
        server_jar="server.jar"
    fi
    
    cat > "$server_dir/start.sh" << EOF
#!/bin/bash
# MohistMC 服务器启动脚本
# 类型: $server_type (混合服 - 插件+模组)
# 版本: $mc_version
# Java: $java_path

cd "\$(dirname "\$0")"

# 读取保存的核心文件名（如果存在）
if [ -f ".server_core" ]; then
    SERVER_JAR=\$(cat ".server_core")
fi

# 如果没有保存的文件名，则动态检测
if [ -z "\$SERVER_JAR" ]; then
    SERVER_JAR=\$(find . -maxdepth 1 -name "*.jar" ! -name "*-installer.jar" ! -name "*.log" ! -name "*.txt" | head -1)
fi

# 验证核心文件存在
if [ -z "\$SERVER_JAR" ] || [ ! -f "\$SERVER_JAR" ]; then
    echo -e "\033[31m错误: 未找到服务器核心文件\033[0m"
    exit 1
fi

# 加载Java配置
if [ -f "java_version.cfg" ]; then
    source "java_version.cfg"
fi

# 验证Java路径
if [ ! -f "\$JAVA_PATH" ] && ! command -v "\$JAVA_PATH" >/dev/null 2>&1; then
    echo -e "\033[33m警告: Java路径 \$JAVA_PATH 不可用，尝试使用系统Java\033[0m"
    if command -v java >/dev/null 2>&1; then
        JAVA_PATH="java"
    else
        echo -e "\033[31m错误: 未找到可用的Java环境\033[0m"
        exit 1
    fi
fi

# MohistMC特定的JVM参数
JVM_OPTS="-Xms2G -Xmx4G -Djava.awt.headless=true -XX:+UseG1GC"
JVM_OPTS="\$JVM_OPTS -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=20"
JVM_OPTS="\$JVM_OPTS -XX:G1ReservePercent=20 -XX:MaxGCPauseMillis=50"
JVM_OPTS="\$JVM_OPTS -XX:G1HeapRegionSize=32M"

# MohistMC优化参数
JVM_OPTS="\$JVM_OPTS -Dmohist.disable.watchdog=true"
JVM_OPTS="\$JVM_OPTS -Dmohist.disable.update=false"
JVM_OPTS="\$JVM_OPTS -Dmohist.disable.plugin.blacklist=false"

# 显示启动信息
echo "=========================================="
echo "启动 MohistMC 服务器"
echo "Java版本: \$(\$JAVA_PATH -version 2>&1 | head -1)"
echo "核心文件: \$SERVER_JAR"
echo "内存分配: 2G-4G"
echo "=========================================="

# 启动MohistMC服务器
\$JAVA_PATH \$JVM_OPTS -jar "\$SERVER_JAR" nogui

# 服务器退出处理
echo "=========================================="
echo "服务器已停止"
echo "退出代码: \$?"
echo "=========================================="
EOF
}

# 创建LiteLoader服务器启动脚本
create_liteloader_start_script() {
    local server_dir=$1
    local java_path=$2
    local mc_version=$3

    # 检测服务器核心文件
    local server_jar=$(detect_server_jar "$server_dir")
    if [ -z "$server_jar" ]; then
        server_jar="server.jar"
    fi

    cat > "$server_dir/start.sh" << EOF
#!/bin/bash
# LiteLoader 服务器启动脚本
# 版本: $mc_version
# Java: $java_path
# 核心文件: $server_jar

cd "\$(dirname "\$0")"

# 读取保存的核心文件名（如果存在）
if [ -f ".server_core" ]; then
    SERVER_JAR=\$(cat ".server_core")
fi

# 如果没有保存的文件名，则动态检测
if [ -z "\$SERVER_JAR" ]; then
    SERVER_JAR=\$(find . -maxdepth 1 -name "*.jar" ! -name "*-installer.jar" ! -name "*.log" ! -name "*.txt" | head -1)
fi

# 验证核心文件存在
if [ -z "\$SERVER_JAR" ] || [ ! -f "\$SERVER_JAR" ]; then
    echo -e "\033[31m错误: 未找到服务器核心文件\033[0m"
    exit 1
fi

# 加载Java配置
if [ -f "java_version.cfg" ]; then
    source "java_version.cfg"
fi

# 验证Java路径
if [ ! -f "\$JAVA_PATH" ] && ! command -v "\$JAVA_PATH" >/dev/null 2>&1; then
    echo -e "\033[33m警告: Java路径 \$JAVA_PATH 不可用，尝试使用系统Java\033[0m"
    if command -v java >/dev/null 2>&1; then
        JAVA_PATH="java"
    else
        echo -e "\033[31m错误: 未找到可用的Java环境\033[0m"
        exit 1
    fi
fi

# LiteLoader特定的JVM参数
JVM_OPTS="-Xms1G -Xmx2G -Djava.awt.headless=true -XX:+UseG1GC"
JVM_OPTS="\$JVM_OPTS -XX:+UnlockExperimentalVMOptions"
JVM_OPTS="\$JVM_OPTS -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20"

# LiteLoader轻量级优化
JVM_OPTS="\$JVM_OPTS -Dliteloader.debug=false"
JVM_OPTS="\$JVM_OPTS -Dliteloader.transformers.preload=true"

# 显示启动信息
echo "=========================================="
echo "启动 LiteLoader 服务器"
echo "核心文件: \$SERVER_JAR"
echo "Java版本: \$(\$JAVA_PATH -version 2>&1 | head -1)"
echo "内存分配: 1G-2G (轻量级)"
echo "=========================================="

# 启动LiteLoader服务器
\$JAVA_PATH \$JVM_OPTS -jar "\$SERVER_JAR" nogui

# 服务器退出处理
echo "=========================================="
echo "服务器已停止"
echo "退出代码: \$?"
echo "=========================================="
EOF
}

# 创建Sponge服务器启动脚本
create_sponge_start_script() {
    local server_dir=$1
    local java_path=$2
    local mc_version=$3

    # 检测服务器核心文件
    local server_jar=$(detect_server_jar "$server_dir")
    if [ -z "$server_jar" ]; then
        server_jar="server.jar"
    fi

    cat > "$server_dir/start.sh" << EOF
#!/bin/bash
# Sponge 服务器启动脚本
# 版本: $mc_version
# Java: $java_path
# 核心文件: $server_jar

cd "\$(dirname "$0")"

# 读取保存的核心文件名（如果存在）
if [ -f ".server_core" ]; then
    SERVER_JAR=\$(cat ".server_core")
fi

# 如果没有保存的文件名，则动态检测
if [ -z "\$SERVER_JAR" ]; then
    SERVER_JAR=\$(find . -maxdepth 1 -name "*.jar" ! -name "*-installer.jar" ! -name "*.log" ! -name "*.txt" | head -1)
fi

# 验证核心文件存在
if [ -z "\$SERVER_JAR" ] || [ ! -f "\$SERVER_JAR" ]; then
    echo -e "\033[31m错误: 未找到服务器核心文件\033[0m"
    exit 1
fi

# 加载Java配置
if [ -f "java_version.cfg" ]; then
    source "java_version.cfg"
fi

# 验证Java路径
if [ ! -f "\$JAVA_PATH" ] && ! command -v "\$JAVA_PATH" >/dev/null 2>&1; then
    echo -e "\033[33m警告: Java路径 \$JAVA_PATH 不可用，尝试使用系统Java\033[0m"
    if command -v java >/dev/null 2>&1; then
        JAVA_PATH="java"
    else
        echo -e "\033[31m错误: 未找到可用的Java环境\033[0m"
        exit 1
    fi
fi

# Sponge特定的JVM参数
JVM_OPTS="-Xms2G -Xmx4G -Djava.awt.headless=true -XX:+UseG1GC"
JVM_OPTS="\$JVM_OPTS -XX:+UnlockExperimentalVMOptions"
JVM_OPTS="\$JVM_OPTS -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20"
JVM_OPTS="\$JVM_OPTS -XX:MaxGCPauseMillis=50"

# Sponge API优化
JVM_OPTS="\$JVM_OPTS -Dsponge.shouldUpdate=false"
JVM_OPTS="\$JVM_OPTS -Dsponge.pluginUpdates=false"

# 显示启动信息
echo "=========================================="
echo "启动 Sponge 服务器"
echo "核心文件: \$SERVER_JAR"
echo "Java版本: \$(\$JAVA_PATH -version 2>&1 | head -1)"
echo "内存分配: 2G-4G"
echo "=========================================="

# 启动Sponge服务器
\$JAVA_PATH \$JVM_OPTS -jar "\$SERVER_JAR" nogui

# 服务器退出处理
echo "=========================================="
echo "服务器已停止"
echo "退出代码: \$?"
echo "=========================================="
EOF
}

# 创建通用启动脚本
create_generic_start_script() {
    local server_dir=$1
    local java_path=$2
    local server_jar=$3
    
    cat > "$server_dir/start.sh" << EOF
#!/bin/bash
# Minecraft服务器通用启动脚本
# Java路径: $java_path
# 核心文件: $server_jar

cd "\$(dirname "\$0")"

# 读取保存的核心文件名（如果存在）
if [ -f ".server_core" ]; then
    SERVER_JAR=\$(cat ".server_core")
fi

# 如果没有保存的文件名，则动态检测
if [ -z "\$SERVER_JAR" ]; then
    SERVER_JAR=\$(find . -maxdepth 1 -name "*.jar" ! -name "*-installer.jar" ! -name "*.log" ! -name "*.txt" | head -1)
fi

# 验证核心文件存在
if [ -z "\$SERVER_JAR" ] || [ ! -f "\$SERVER_JAR" ]; then
    echo -e "\033[31m错误: 未找到服务器核心文件\033[0m"
    exit 1
fi

# 加载Java版本配置
if [ -f "java_version.cfg" ]; then
    source "java_version.cfg"
fi

# 验证Java路径
if [ ! -f "\$JAVA_PATH" ] && ! command -v "\$JAVA_PATH" >/dev/null 2>&1; then
    echo -e "\033[33m警告: Java路径 \$JAVA_PATH 不可用，尝试使用系统Java\033[0m"
    if command -v java >/dev/null 2>&1; then
        JAVA_PATH="java"
    else
        echo -e "\033[31m错误: 未找到可用的Java环境\033[0m"
        exit 1
    fi
fi

# 基本JVM参数
JVM_OPTS="-Xms2G -Xmx4G -Djava.awt.headless=true -XX:+UseG1GC"
JVM_OPTS="\$JVM_OPTS -XX:+UnlockExperimentalVMOptions"
JVM_OPTS="\$JVM_OPTS -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20"

# 自动检测并添加服务器特定参数
if [ -f "fabric-server-launch.jar" ]; then
    JVM_OPTS="\$JVM_OPTS -Dfabric.dli.config=config.json"
fi

if [ -d "mods" ]; then
    JVM_OPTS="\$JVM_OPTS -Dforge.logging.console.level=info"
    JVM_OPTS="\$JVM_OPTS -Dlog4j.configurationFile=log4j2.xml"
fi

if [ -d "plugins" ]; then
    JVM_OPTS="\$JVM_OPTS -Dpaper.disableChannelLimits=true"
fi

# 显示启动信息
echo "=========================================="
echo "正在启动 Minecraft 服务器"
echo "Java版本: \$(\$JAVA_PATH -version 2>&1 | head -1)"
echo "核心文件: \$SERVER_JAR"
echo "内存分配: 2G-4G"
echo "=========================================="

# 启动服务器
\$JAVA_PATH \$JVM_OPTS -jar "\$SERVER_JAR" nogui

# 服务器退出处理
echo "=========================================="
echo "服务器已停止"
echo "退出代码: \$?"
echo "=========================================="
EOF
}

# 服务器启动和运行管理

# 启动服务器
start_server() {
    local server_name="$1"
    local server_dir="$MCSERVER_DIR/$server_name"
    
    # 检查服务器目录是否存在
    if [ ! -d "$server_dir" ]; then
        if [ "$NO_GUI" = "true" ]; then
            echo "错误: 服务器目录不存在: $server_dir"
        else
            show_msg "错误" "服务器目录不存在"
        fi
        return 1
    fi
    
    
    # 检查是否已运行
    if is_server_running "$server_name"; then
        if [ "$NO_GUI" = "true" ]; then
            echo "服务器已经在运行中"
        else
            show_msg "信息" "服务器已经在运行中"
        fi
        return 0
    fi
    
    # 检查协议文件
    if [ ! -f "$server_dir/eula.txt" ]; then
        echo "eula=true" > "$server_dir/eula.txt"
        if [ "$NO_GUI" = "true" ]; then
            echo "已创建并同意 EULA 协议"
        fi
    fi
    
    # 检查启动脚本
    if [ ! -f "$server_dir/start.sh" ]; then
        # 获取服务器信息
        local server_info=$(jq -r --arg name "$server_name" '.servers[] | select(.name == $name)' "$CONFIG_FILE")
        local server_type=$(echo "$server_info" | jq -r '.type')
        local mc_version=$(echo "$server_info" | jq -r '.version')
        
        # 创建启动脚本
        create_start_script "$server_dir" "$server_type" "$mc_version"
    fi
    
    # 检查核心文件
    local server_jar=$(detect_server_jar "$server_dir")
    if [ -z "$server_jar" ]; then
        if [ "$NO_GUI" = "true" ]; then
            echo "错误: 找不到服务器核心文件"
        else
            show_msg "错误" "找不到服务器核心文件"
        fi
        return 1
    fi

    # 获取服务器类型
    local server_info=$(jq -r --arg name "$server_name" '.servers[] | select(.name == $name)' "$CONFIG_FILE")
    local server_type=$(echo "$server_info" | jq -r '.type')

    # 基岩版特殊处理：使用 start.sh
    if [ "$server_type" = "bedrock" ]; then
        cd "$server_dir"
        if [ -f "start.sh" ]; then
            chmod +x start.sh
            ./start.sh
            return $?
        fi
    fi

    # 检查Java环境（非基岩版）
    if ! check_java_environment "$server_dir" "$server_name"; then
        if [ "$NO_GUI" = "true" ]; then
            echo "错误: Java环境检查失败"
        else
            show_msg "错误" "Java环境检查失败"
        fi
        return 1
    fi

    # 根据模式执行
    if [ "$NO_GUI" = "true" ]; then
        # 无GUI模式直接启动
        echo "启动服务器 '$server_name'..."
        cd "$server_dir"
        ./start.sh
    else
        # GUI模式
        clear
        echo -e "${BLUE}正在启动服务器 '$server_name'...${NC}"
        
        # 保存脚本路径用于重启
        local manager_script_path="$SCRIPT_PATH"
        
        # 结束图形界面
        exec 3>&-
        exec 4>&-
        
        # 启动服务器
        cd "$server_dir"
        ./start.sh
        
        # 服务器停止后重启管理器
        sleep 2
        exec "$manager_script_path"
    fi
}

# 检查Java环境
check_java_environment() {
    local server_dir=$1
    local server_name=$2
    
    # 检查Java版本配置
    local java_path="java"
    local jdk_version=""
    
    if [ -f "$server_dir/java_version.cfg" ]; then
        source "$server_dir/java_version.cfg"
        if [ -n "$JAVA_PATH" ]; then
            java_path="$JAVA_PATH"
        fi
        if [ -n "$JDK_VERSION" ]; then
            jdk_version="$JDK_VERSION"
        fi
    fi
    
    # 检查Java是否可用
    if ! command -v "$java_path" >/dev/null 2>&1; then
        if [ -n "$jdk_version" ]; then
            echo -e "${YELLOW}警告: 配置的Java路径 $java_path 不可用${NC}"
            if ui_confirm "服务器 '$server_name' 配置的Java环境不可用。\n\n是否尝试自动安装JDK $jdk_version？"; then
                if install_jdk_version "$jdk_version"; then
                    # 更新Java路径
                    java_path="$MCJDK_DIR/jdk$jdk_version/bin/java"
                    echo -e "${GREEN}JDK $jdk_version 安装成功${NC}"
                else
                    echo -e "${RED}JDK 安装失败，尝试使用系统Java${NC}"
                    java_path="java"
                fi
            else
                echo -e "${YELLOW}使用系统Java环境${NC}"
                java_path="java"
            fi
        else
            echo -e "${YELLOW}未找到Java环境，尝试使用系统Java${NC}"
            java_path="java"
        fi
    fi
    
    # 最终检查
    if ! command -v "$java_path" >/dev/null 2>&1; then
        echo -e "${RED}错误: 未找到可用的Java环境${NC}"
        echo -e "${YELLOW}请安装Java或使用管理器安装JDK${NC}"
        return 1
    fi
    
    # 验证Java版本
    local java_version=$("$java_path" -version 2>&1 | head -1 | grep -o '[0-9._]*' | head -1)
    echo -e "${GREEN}使用Java版本: $java_version${NC}"
    
    return 0
}

# Java环境自动修复功能
auto_fix_java_environment() {
    local server_name="$1"
    local server_dir="$MCSERVER_DIR/$server_name"
    
    # 获取服务器信息
    local server_info=$(jq -r --arg name "$server_name" '.servers[] | select(.name == $name)' "$CONFIG_FILE")
    local mc_version=$(echo "$server_info" | jq -r '.version')
    
    # 确定所需的JDK版本
    local required_jdk=$(get_required_jdk_version "$mc_version")
    
    echo -e "${BLUE}检测到服务器 '$server_name' 需要JDK $required_jdk${NC}"

    if ui_confirm "服务器 '$server_name' (版本 $mc_version) 需要JDK $required_jdk，但当前Java环境不可用。\n\n是否立即安装并配置？"; then
        if install_jdk_version "$required_jdk"; then
            # 配置服务器使用该JDK
            if configure_server_jdk "$server_name" "$required_jdk"; then
                ui_message "成功" "JDK $required_jdk 安装并配置成功"
                return 0
            else
                ui_message "错误" "JDK配置失败"
                return 1
            fi
        else
            ui_message "错误" "JDK安装失败"
            return 1
        fi
    else
        ui_message "信息" "已取消Java环境修复"
        return 1
    fi
}

# 备份服务器
backup_server() {
    local server_name="$1"
    local server_dir="$MCSERVER_DIR/$server_name"
    local backup_dir="$server_dir/backups"

    # 检查服务器目录是否存在
    if [ ! -d "$server_dir" ]; then
        if [ "$NO_GUI" = "true" ]; then
            echo "错误: 服务器目录不存在: $server_dir"
        else
            show_msg "错误" "服务器目录不存在"
        fi
        return 1
    fi

    # 创建备份目录
    mkdir -p "$backup_dir"

    # 生成备份文件名
    local timestamp=$(date +%Y%m%d_%H%M%S)
    local backup_file="$backup_dir/${server_name}_${timestamp}.tar.gz"

    # 显示备份信息
    if [ "$NO_GUI" = "true" ]; then
        echo "正在备份服务器 '$server_name'..."
        echo "备份文件: $backup_file"
    else
        show_msg "信息" "正在备份服务器，请稍候..."
    fi

    # 排除不需要备份的目录和文件
    local exclude_args="--exclude=logs --exclude=cache --exclude=backups --exclude=*.log --exclude=*.lock"

    # 执行备份
    if tar $exclude_args -czf "$backup_file" -C "$server_dir" . 2>/dev/null; then
        # 记录备份信息
        local backup_info_file="$backup_dir/backup_info.txt"
        echo "服务器: $server_name" >> "$backup_info_file"
        echo "备份时间: $(date +'%Y-%m-%d %H:%M:%S')" >> "$backup_info_file"
        echo "备份文件: $(basename "$backup_file")" >> "$backup_info_file"
        echo "---" >> "$backup_info_file"

        if [ "$NO_GUI" = "true" ]; then
            echo "备份完成: $(basename "$backup_file")"
        else
            show_msg "成功" "服务器备份完成"
        fi

        # 清理旧备份（保留最近10个）
        local backup_count=$(ls -1 "$backup_dir"/*.tar.gz 2>/dev/null | wc -l)
        if [ "$backup_count" -gt 10 ]; then
            ls -1t "$backup_dir"/*.tar.gz | tail -n +11 | xargs -r rm -f
            if [ "$NO_GUI" = "true" ]; then
                echo "已清理旧备份，保留最近10个"
            fi
        fi

        return 0
    else
        if [ "$NO_GUI" = "true" ]; then
            echo "错误: 备份失败"
        else
            show_msg "错误" "服务器备份失败"
        fi
        return 1
    fi
}

# 服务器文件与配置

# 服务器文件与配置
# 在manage_server_files()函数中添加"快捷设置配置"选项
manage_server_files() {
    local server_name=$1
    local server_dir="$MCSERVER_DIR/$server_name"

    # CLI 模式调用 CLI 版本
    if [ "$NO_GUI" = "true" ]; then
        cli_manage_server_files "$server_name"
        return
    fi

    # 获取服务器信息
    local server_info=$(jq -r --arg name "$server_name" '.servers[] | select(.name == $name)' "$CONFIG_FILE")
    local server_type=$(echo "$server_info" | jq -r '.type')

    while true; do
        choice=$(safe_whiptail --nocancel --clear \
            --title "文件与配置: $server_name ($server_type)" \
            --menu "请选择操作：" 20 60 10 \
            "1" "编辑配置文件" \
            "2" "查看文件列表" \
            "3" "查看核心信息" \
            "4" "快捷设置配置" \
            "5" "重新生成启动脚本" \
            "0" "返回管理服务器" \
            3>&1 1>&2 2>&3)

        case $choice in
            1) edit_server_file "$server_name" ;;
            2) list_server_files "$server_name" ;;
            3) show_server_core_info "$server_name" ;;
            4) quick_edit_server_properties "$server_name" ;;
            5) regenerate_start_script "$server_name" ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 快捷设置配置函数
quick_edit_server_properties() {
    local server_name="$1"
    local server_dir="$MCSERVER_DIR/$server_name"
    local properties_file="$server_dir/server.properties"

    # CLI 模式提示用户使用 GUI
    if [ "$NO_GUI" = "true" ]; then
        echo ""
        echo "快捷设置配置需要图形界面，请在 GUI 模式下运行"
        echo "或者直接编辑 server.properties 文件: $properties_file"
        echo ""
        echo "按回车键返回..."
        read
        return
    fi

    # 检查server.properties文件是否存在
    if [ ! -f "$properties_file" ]; then
        show_msg "警告" "server.properties 文件不存在。请启动一次服务器后再进行配置"
        return
    fi

    # 获取服务器信息用于配置推荐
    local server_info=$(jq -r --arg name "$server_name" '.servers[] | select(.name == $name)' "$CONFIG_FILE")
    local server_type=$(echo "$server_info" | jq -r '.type')
    local mc_version=$(echo "$server_info" | jq -r '.version')

    while true; do
        # 显示当前配置摘要
        local current_config=$(get_server_properties_summary "$properties_file")

        choice=$(safe_whiptail --nocancel --clear \
            --title "快捷设置配置: $server_name" \
            --menu "当前配置摘要:\n$current_config\n\n请选择配置类别：" 25 60 15 \
            "1" "基本参数设置" \
            "2" "游戏规则设置" \
            "3" "性能优化设置" \
            "4" "世界生成设置" \
            "5" "高级安全设置" \
            "6" "查看所有配置" \
            "7" "配置参数推荐" \
            "8" "验证配置参数" \
            "9" "备份配置参数" \
            "0" "返回文件与配置" \
            3>&1 1>&2 2>&3)
        
        case $choice in
            1) edit_basic_settings "$server_name" "$properties_file" "$server_type" "$mc_version" ;;
            2) edit_game_rules "$server_name" "$properties_file" "$server_type" ;;
            3) edit_performance_settings "$server_name" "$properties_file" "$server_type" ;;
            4) edit_world_settings "$server_name" "$properties_file" "$server_type" ;;
            5) edit_security_settings "$server_name" "$properties_file" "$server_type" ;;
            6) view_all_properties "$server_name" "$properties_file" ;;
            7) apply_recommended_config "$server_name" "$properties_file" "$server_type" "$mc_version" ;;
            8) 
                local validation_result=$(validate_server_properties "$properties_file")
                show_msg "配置验证" "$validation_result"
                ;;
            9) 
                backup_server_properties "$properties_file" "$server_name"
                show_msg "成功" "配置备份完成"
                ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 获取服务器配置摘要
get_server_properties_summary() {
    local properties_file="$1"
    
    if [ ! -f "$properties_file" ]; then
        echo "配置文件不存在"
        return
    fi
    
    local summary=""
    
    # 读取关键配置项
    local port=$(get_property_value "$properties_file" "server-port")
    local gamemode=$(get_property_value "$properties_file" "gamemode")
    local difficulty=$(get_property_value "$properties_file" "difficulty")
    local max_players=$(get_property_value "$properties_file" "max-players")
    local view_distance=$(get_property_value "$properties_file" "view-distance")
    local online_mode=$(get_property_value "$properties_file" "online-mode")
    local pvp=$(get_property_value "$properties_file" "pvp")
    
    summary+="端口: ${port:-25565} | 模式: ${gamemode:-survival}\n"
    summary+="难度: ${difficulty:-easy} | 玩家: ${max_players:-20}\n"
    summary+="视距: ${view_distance:-10} | 在线验证: ${online_mode:-true}\n"
    summary+="PVP: ${pvp:-true}"
    
    echo "$summary"
}

# 获取配置项值
get_property_value() {
    local file="$1"
    local key="$2"
    
    if [ ! -f "$file" ]; then
        return
    fi
    
    # 使用grep查找配置项，排除注释行
    grep -v "^#" "$file" | grep "^$key=" | cut -d'=' -f2-
}

# 设置配置项值
set_property_value() {
    local file="$1"
    local key="$2"
    local value="$3"
    
    if [ ! -f "$file" ]; then
        return 1
    fi
    
    # 创建临时文件
    local temp_file="${file}.tmp"
    
    # 如果配置项已存在，则替换；否则添加到文件末尾
    if grep -q "^$key=" "$file"; then
        # 替换现有配置项
        sed "s/^$key=.*/$key=$value/" "$file" > "$temp_file"
    else
        # 添加到文件末尾
        cp "$file" "$temp_file"
        echo "$key=$value" >> "$temp_file"
    fi
    
    # 替换原文件
    mv "$temp_file" "$file"
    return 0
}

# 基本设置编辑
edit_basic_settings() {
    local server_name="$1"
    local properties_file="$2"
    local server_type="$3"
    local mc_version="$4"

    # CLI 模式提示用户使用 GUI
    if [ "$NO_GUI" = "true" ]; then
        echo ""
        echo "基本设置编辑需要图形界面"
        echo "请在 GUI 模式下运行或直接编辑 server.properties 文件"
        echo ""
        return
    fi

    while true; do
        # 读取当前值
        local port=$(get_property_value "$properties_file" "server-port")
        local gamemode=$(get_property_value "$properties_file" "gamemode")
        local difficulty=$(get_property_value "$properties_file" "difficulty")
        local level_name=$(get_property_value "$properties_file" "level-name")
        local server_name_prop=$(get_property_value "$properties_file" "server-name")

        choice=$(safe_whiptail --nocancel --clear \
            --title "基本设置: $server_name" \
            --menu "当前设置:\n端口: ${port:-25565} | 模式: ${gamemode:-survival}\n难度: ${difficulty:-easy} | 世界: ${level_name:-world}\n\n请选择要修改的设置：" 20 70 10 \
            "1" "服务器端口 (当前: ${port:-25565})" \
            "2" "游戏模式 (当前: ${gamemode:-survival})" \
            "3" "游戏难度 (当前: ${difficulty:-easy})" \
            "4" "世界名称 (当前: ${level_name:-world})" \
            "5" "服务器名称 (当前: ${server_name_prop:-Minecraft Server})" \
            "0" "返回配置菜单" \
            3>&1 1>&2 2>&3)

        case $choice in
            1) edit_port_setting "$properties_file" ;;
            2) edit_gamemode_setting "$properties_file" ;;
            3) edit_difficulty_setting "$properties_file" ;;
            4) edit_level_name_setting "$properties_file" ;;
            5) edit_server_name_setting "$properties_file" ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 编辑端口设置
edit_port_setting() {
    local properties_file="$1"
    local current_port=$(get_property_value "$properties_file" "server-port")
    
    local new_port=$(ui_input "请输入服务器端口 (1024-65535)" "${current_port:-25565}")
    
    if [ $? -ne 0 ] || [ -z "$new_port" ]; then
        return
    fi
    
    # 验证端口号
    if ! [[ "$new_port" =~ ^[0-9]+$ ]] || [ "$new_port" -lt 1024 ] || [ "$new_port" -gt 65535 ]; then
        show_msg "错误" "端口号必须是 1024-65535 之间的数字"
        return
    fi
    
    # 检查端口是否被占用
    if lsof -i :$new_port >/dev/null 2>&1; then
        ui_confirm "端口 $new_port 可能已被占用。是否继续使用？"
        if [ $? -ne 0 ]; then
            return
        fi
    fi
    
    set_property_value "$properties_file" "server-port" "$new_port"
    show_msg "成功" "服务器端口已设置为: $new_port"
}

# 编辑游戏模式设置
edit_gamemode_setting() {
    local properties_file="$1"
    local current_gamemode=$(get_property_value "$properties_file" "gamemode")

    if [ "$NO_GUI" = "true" ]; then
        choice=$(cli_menu_select "选择游戏模式" \
            "survival:生存模式" \
            "creative:创造模式" \
            "adventure:冒险模式" \
            "spectator:观察者模式")
    else
        choice=$(safe_whiptail --menu "选择游戏模式:" 15 40 5 \
            "survival" "生存模式" \
            "creative" "创造模式" \
            "adventure" "冒险模式" \
            "spectator" "观察者模式" \
            3>&1 1>&2 2>&3)
    fi

    if [ $? -eq 0 ] && [ -n "$choice" ]; then
        set_property_value "$properties_file" "gamemode" "$choice"
        show_msg "成功" "游戏模式已设置为: $choice"
    fi
}

# 编辑游戏难度设置
edit_difficulty_setting() {
    local properties_file="$1"
    local current_difficulty=$(get_property_value "$properties_file" "difficulty")

    if [ "$NO_GUI" = "true" ]; then
        choice=$(cli_menu_select "选择游戏难度" \
            "peaceful:和平" \
            "easy:简单" \
            "normal:普通" \
            "hard:困难")
    else
        choice=$(safe_whiptail --menu "选择游戏难度:" 15 50 5 \
            "peaceful" "和平" \
            "easy" "简单" \
            "normal" "普通" \
            "hard" "困难" \
            3>&1 1>&2 2>&3)
    fi
    
    if [ $? -eq 0 ] && [ -n "$choice" ]; then
        set_property_value "$properties_file" "difficulty" "$choice"
        show_msg "成功" "游戏难度已设置为: $choice"
    fi
}

# 编辑世界名称设置
edit_level_name_setting() {
    local properties_file="$1"
    local current_name=$(get_property_value "$properties_file" "level-name")
    
    local new_name=$(ui_input "请输入世界名称" "${current_name:-world}")
    
    if [ $? -eq 0 ] && [ -n "$new_name" ]; then
        # 验证名称格式
        if ! [[ "$new_name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
            show_msg "错误" "世界名称只能包含字母、数字、下划线和连字符"
            return
        fi
        
        set_property_value "$properties_file" "level-name" "$new_name"
        show_msg "成功" "世界名称已设置为: $new_name"
    fi
}

# 编辑服务器名称设置
edit_server_name_setting() {
    local properties_file="$1"
    local current_name=$(get_property_value "$properties_file" "server-name")
    
    local new_name=$(ui_input "请输入服务器显示名称" "${current_name:-Minecraft Server}")
    
    if [ $? -eq 0 ] && [ -n "$new_name" ]; then
        set_property_value "$properties_file" "server-name" "$new_name"
        show_msg "成功" "服务器名称已设置为: $new_name"
    fi
}

# 编辑最大玩家数设置
edit_max_players_setting() {
    local properties_file="$1"
    local current_players=$(get_property_value "$properties_file" "max-players")
    
    local new_players=$(ui_input "请输入最大玩家数 (1-1000)" "${current_players:-20}")
    
    if [ $? -ne 0 ] || [ -z "$new_players" ]; then
        return
    fi
    
    # 验证玩家数
    if ! [[ "$new_players" =~ ^[0-9]+$ ]] || [ "$new_players" -lt 1 ] || [ "$new_players" -gt 1000 ]; then
        show_msg "错误" "玩家数必须是 1-1000 之间的数字"
        return
    fi
    
    set_property_value "$properties_file" "max-players" "$new_players"
    show_msg "成功" "最大玩家数已设置为: $new_players"
}

# 编辑视距设置
edit_view_distance_setting() {
    local properties_file="$1"
    local server_type="$2"
    local current_distance=$(get_property_value "$properties_file" "view-distance")
    
    # 根据服务器类型推荐范围
    local max_distance=16
    case "$server_type" in
        "folia") max_distance=12 ;;
        "paper"|"spigot") max_distance=14 ;;
        *) max_distance=10 ;;
    esac
    
    local new_distance=$(ui_input "请输入视距 (2-$max_distance)

推荐值:
- 低性能设备: 4-6
- 标准服务器: 8-10
- 高性能服务器: 10-$max_distance" "${current_distance:-10}")
    
    if [ $? -ne 0 ] || [ -z "$new_distance" ]; then
        return
    fi
    
    # 验证视距
    if ! [[ "$new_distance" =~ ^[0-9]+$ ]] || [ "$new_distance" -lt 2 ] || [ "$new_distance" -gt "$max_distance" ]; then
        show_msg "错误" "视距必须是 2-$max_distance 之间的数字"
        return
    fi
    
    set_property_value "$properties_file" "view-distance" "$new_distance"
    show_msg "成功" "视距已设置为: $new_distance"
}

# 编辑在线验证模式
edit_online_mode_setting() {
    local properties_file="$1"
    local current_mode=$(get_property_value "$properties_file" "online-mode")
    
    ui_confirm "是否启用在线验证？\n\n启用: 只有正版玩家可以加入\n禁用: 允许离线模式玩家加入\n\n当前设置: ${current_mode:-true}"
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "online-mode" "true"
        show_msg "成功" "已启用在线验证 (正版验证)"
    else
        set_property_value "$properties_file" "online-mode" "false"
        show_msg "成功" "已禁用在线验证 (允许离线模式)"
    fi
}

# 游戏规则设置
edit_game_rules() {
    local server_name="$1"
    local properties_file="$2"
    local server_type="$3"
    
    while true; do
        # 读取当前值
        local pvp=$(get_property_value "$properties_file" "pvp")
        local spawn_animals=$(get_property_value "$properties_file" "spawn-animals")
        local spawn_monsters=$(get_property_value "$properties_file" "spawn-monsters")
        local allow_nether=$(get_property_value "$properties_file" "allow-nether")
        local generate_structures=$(get_property_value "$properties_file" "generate-structures")
        
        choice=$(safe_whiptail --nocancel --clear \
            --title "游戏规则设置: $server_name" \
            --menu "当前设置:\nPVP: ${pvp:-true} | 生成动物: ${spawn_animals:-true}\n生成怪物: ${spawn_monsters:-true} | 下界: ${allow_nether:-true}\n生成结构: ${generate_structures:-true}\n\n请选择要修改的规则：" 20 70 12 \
            "1" "PVP 设置 (当前: ${pvp:-true})" \
            "2" "动物生成 (当前: ${spawn_animals:-true})" \
            "3" "怪物生成 (当前: ${spawn_monsters:-true})" \
            "4" "下界维度 (当前: ${allow_nether:-true})" \
            "5" "生成结构 (当前: ${generate_structures:-true})" \
            "6" "飞行设置" \
            "0" "返回配置菜单" \
            3>&1 1>&2 2>&3)
        
        case $choice in
            1) edit_pvp_setting "$properties_file" ;;
            2) edit_spawn_animals_setting "$properties_file" ;;
            3) edit_spawn_monsters_setting "$properties_file" ;;
            4) edit_allow_nether_setting "$properties_file" ;;
            5) edit_generate_structures_setting "$properties_file" ;;
            6) edit_flight_setting "$properties_file" "$server_type" ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 编辑PVP设置
edit_pvp_setting() {
    local properties_file="$1"
    local current_pvp=$(get_property_value "$properties_file" "pvp")
    
    ui_confirm "是否允许玩家之间互相攻击？\n\n当前设置: ${current_pvp:-true}"
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "pvp" "true"
        show_msg "成功" "已启用 PVP (玩家可以互相攻击)"
    else
        set_property_value "$properties_file" "pvp" "false"
        show_msg "成功" "已禁用 PVP (和平模式)"
    fi
}

# 性能优化设置
edit_performance_settings() {
    local server_name="$1"
    local properties_file="$2"
    local server_type="$3"
    
    while true; do
        # 读取当前值
        local max_tick_time=$(get_property_value "$properties_file" "max-tick-time")
        local max_world_size=$(get_property_value "$properties_file" "max-world-size")
        local simulation_distance=$(get_property_value "$properties_file" "simulation-distance")
        
        choice=$(safe_whiptail --nocancel --clear \
            --title "性能优化设置: $server_name" \
            --menu "当前设置:\n最大tick时间: ${max_tick_time:-60000}ms\n世界大小限制: ${max_world_size:-29999984}\n模拟距离: ${simulation_distance:-10}\n\n请选择要修改的设置：" 20 70 10 \
            "1" "最大tick时间 (当前: ${max_tick_time:-60000}ms)" \
            "2" "世界大小限制 (当前: ${max_world_size:-29999984})" \
            "3" "模拟距离 (当前: ${simulation_distance:-10})" \
            "4" "实体优化设置" \
            "5" "区块加载优化" \
            "0" "返回配置菜单" \
            3>&1 1>&2 2>&3)
        
        case $choice in
            1) edit_max_tick_time_setting "$properties_file" "$server_type" ;;
            2) edit_max_world_size_setting "$properties_file" ;;
            3) edit_simulation_distance_setting "$properties_file" "$server_type" ;;
            4) edit_entity_optimization "$properties_file" "$server_type" ;;
            5) edit_chunk_loading_optimization "$properties_file" "$server_type" ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 根据服务器类型推荐配置
apply_recommended_config() {
    local server_name="$1"
    local properties_file="$2"
    local server_type="$3"
    local mc_version="$4"
    
    ui_confirm "确定要应用针对 $server_type 服务器的推荐配置吗？\n\n这将根据服务器类型自动优化各项设置。"
    
    if [ $? -ne 0 ]; then
        return
    fi
    
    # 根据服务器类型应用推荐配置
    case "$server_type" in
        "vanilla")
            # 原版服务器推荐配置
            set_property_value "$properties_file" "view-distance" "10"
            set_property_value "$properties_file" "simulation-distance" "8"
            set_property_value "$properties_file" "max-tick-time" "60000"
            set_property_value "$properties_file" "network-compression-threshold" "256"
            set_property_value "$properties_file" "max-players" "20"
            set_property_value "$properties_file" "spawn-protection" "16"
            ;;
            
        "paper"|"spigot")
            # Paper/Spigot 推荐配置
            set_property_value "$properties_file" "view-distance" "8"
            set_property_value "$properties_file" "simulation-distance" "6"
            set_property_value "$properties_file" "max-tick-time" "30000"
            set_property_value "$properties_file" "network-compression-threshold" "256"
            set_property_value "$properties_file" "max-players" "50"
            set_property_value "$properties_file" "spawn-protection" "0"
            set_property_value "$properties_file" "use-native-transport" "true"
            ;;
            
        "folia")
            # Folia 多线程服务器推荐配置
            set_property_value "$properties_file" "view-distance" "6"
            set_property_value "$properties_file" "simulation-distance" "4"
            set_property_value "$properties_file" "max-tick-time" "15000"
            set_property_value "$properties_file" "network-compression-threshold" "512"
            set_property_value "$properties_file" "max-players" "100"
            set_property_value "$properties_file" "spawn-protection" "0"
            set_property_value "$properties_file" "player-idle-timeout" "0"
            ;;
            
        "forge"|"fabric")
            # 模组服务器推荐配置
            set_property_value "$properties_file" "view-distance" "6"
            set_property_value "$properties_file" "simulation-distance" "4"
            set_property_value "$properties_file" "max-tick-time" "90000"
            set_property_value "$properties_file" "network-compression-threshold" "512"
            set_property_value "$properties_file" "max-players" "10"
            set_property_value "$properties_file" "spawn-protection" "16"
            ;;
            
        *)
            # 默认配置
            set_property_value "$properties_file" "view-distance" "8"
            set_property_value "$properties_file" "simulation-distance" "6"
            set_property_value "$properties_file" "max-tick-time" "60000"
            set_property_value "$properties_file" "network-compression-threshold" "256"
            ;;
    esac
    
    # 根据Minecraft版本调整配置
    local major_version=$(echo "$mc_version" | awk -F. '{print $1}')
    local minor_version=$(echo "$mc_version" | awk -F. '{print $2}')
    
    if [ "$major_version" -eq 1 ] && [ "$minor_version" -ge 17 ]; then
        # 1.17+ 版本特有设置
        set_property_value "$properties_file" "simulation-distance" "6"
    fi
    
    if [ "$major_version" -eq 1 ] && [ "$minor_version" -ge 18 ]; then
        # 1.18+ 版本特有设置
        set_property_value "$properties_file" "max-build-height" "320"
    fi
    
    show_msg "成功" "已应用 $server_type 服务器推荐配置"
}

# 编辑网络压缩设置
edit_network_compression_setting() {
    local properties_file="$1"
    local server_type="$2"
    local current_compression=$(get_property_value "$properties_file" "network-compression-threshold")

    if [ "$NO_GUI" = "true" ]; then
        compression_choice=$(cli_menu_select "选择网络压缩阈值 (值越小压缩越强，-1禁用压缩)" \
            "-1:禁用压缩 (高性能网络)" \
            "64:高压缩 (低带宽)" \
            "256:标准压缩 (推荐)" \
            "512:低压缩 (高带宽)")
    else
        compression_choice=$(safe_whiptail --menu "选择网络压缩阈值:\n\n值越小压缩越强，-1禁用压缩" 15 50 5 \
            "-1" "禁用压缩 (高性能网络)" \
            "64" "高压缩 (低带宽)" \
            "256" "标准压缩 (推荐)" \
            "512" "低压缩 (高带宽)" \
            3>&1 1>&2 2>&3)
    fi

    if [ $? -eq 0 ] && [ -n "$compression_choice" ]; then
        set_property_value "$properties_file" "network-compression-threshold" "$compression_choice"
        show_msg "成功" "网络压缩阈值已设置为: $compression_choice"
    fi
}

# 编辑白名单设置
edit_whitelist_setting() {
    local properties_file="$1"
    local current_whitelist=$(get_property_value "$properties_file" "white-list")
    
    ui_confirm "是否启用白名单？\n\n启用后只有白名单中的玩家可以加入服务器。"
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "white-list" "true"
        show_msg "成功" "已启用白名单，请编辑 whitelist.json 文件添加玩家"
    else
        set_property_value "$properties_file" "white-list" "false"
        show_msg "成功" "已禁用白名单"
    fi
}

# 编辑动物生成设置
edit_spawn_animals_setting() {
    local properties_file="$1"
    local current_setting=$(get_property_value "$properties_file" "spawn-animals")
    
    ui_confirm "是否允许生成动物？\n\n禁用后世界不会自然生成动物。"
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "spawn-animals" "true"
        show_msg "成功" "已允许动物生成"
    else
        set_property_value "$properties_file" "spawn-animals" "false"
        show_msg "成功" "已禁止动物生成"
    fi
}

# 编辑怪物生成设置
edit_spawn_monsters_setting() {
    local properties_file="$1"
    local current_setting=$(get_property_value "$properties_file" "spawn-monsters")
    
    ui_confirm "是否允许生成怪物？\n\n禁用后世界不会自然生成敌对生物。"
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "spawn-monsters" "true"
        show_msg "成功" "已允许怪物生成"
    else
        set_property_value "$properties_file" "spawn-monsters" "false"
        show_msg "成功" "已禁止怪物生成"
    fi
}

# 编辑下界维度设置
edit_allow_nether_setting() {
    local properties_file="$1"
    local current_setting=$(get_property_value "$properties_file" "allow-nether")
    
    ui_confirm "是否允许下界维度？\n\n禁用后玩家无法进入下界。"
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "allow-nether" "true"
        show_msg "成功" "已允许下界维度"
    else
        set_property_value "$properties_file" "allow-nether" "false"
        show_msg "成功" "已禁止下界维度"
    fi
}

# 编辑结构生成设置
edit_generate_structures_setting() {
    local properties_file="$1"
    local current_setting=$(get_property_value "$properties_file" "generate-structures")
    
    ui_confirm "是否生成世界结构？\n\n包括村庄、要塞、神庙等自然生成结构。"
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "generate-structures" "true"
        show_msg "成功" "已启用结构生成"
    else
        set_property_value "$properties_file" "generate-structures" "false"
        show_msg "成功" "已禁用结构生成"
    fi
}

# 编辑飞行设置
edit_flight_setting() {
    local properties_file="$1"
    local server_type="$2"
    
    # 注意：原版服务器没有直接的飞行设置，这里设置 allow-flight
    local current_flight=$(get_property_value "$properties_file" "allow-flight")
    
    ui_confirm "是否允许飞行？\n\n允许玩家在生存模式下飞行（需要权限）。"
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "allow-flight" "true"
        show_msg "成功" "已允许飞行"
    else
        set_property_value "$properties_file" "allow-flight" "false"
        show_msg "成功" "已禁止飞行"
    fi
}

# 编辑最大tick时间设置
edit_max_tick_time_setting() {
    local properties_file="$1"
    local server_type="$2"
    local current_tick_time=$(get_property_value "$properties_file" "max-tick-time")
    
    # 根据服务器类型推荐值
    local default_value="60000"
    case "$server_type" in
        "paper"|"spigot") default_value="30000" ;;
        "folia") default_value="15000" ;;
        "forge"|"fabric") default_value="90000" ;;
    esac
    
    local new_tick_time=$(ui_input "请输入最大tick时间(毫秒)

服务器处理一个tick的最大时间，超时则重启。
推荐值: $default_value ms" "${current_tick_time:-$default_value}")
    
    if [ $? -eq 0 ] && [ -n "$new_tick_time" ]; then
        if ! [[ "$new_tick_time" =~ ^[0-9]+$ ]] || [ "$new_tick_time" -lt 1000 ]; then
            show_msg "错误" "tick时间必须大于1000毫秒"
            return
        fi
        
        set_property_value "$properties_file" "max-tick-time" "$new_tick_time"
        show_msg "成功" "最大tick时间已设置为: ${new_tick_time}ms"
    fi
}

# 编辑世界大小限制
edit_max_world_size_setting() {
    local properties_file="$1"
    local current_size=$(get_property_value "$properties_file" "max-world-size")
    
    local new_size=$(ui_input "请输入世界大小限制(区块)

设置世界边界大小，1=1x1区块，29999984=6000x6000区块" "${current_size:-29999984}")
    
    if [ $? -eq 0 ] && [ -n "$new_size" ]; then
        if ! [[ "$new_size" =~ ^[0-9]+$ ]] || [ "$new_size" -lt 1 ] || [ "$new_size" -gt 29999984 ]; then
            show_msg "错误" "世界大小必须在1-29999984之间"
            return
        fi
        
        set_property_value "$properties_file" "max-world-size" "$new_size"
        show_msg "成功" "世界大小限制已设置为: $new_size"
    fi
}

# 编辑模拟距离设置
edit_simulation_distance_setting() {
    local properties_file="$1"
    local server_type="$2"
    local current_distance=$(get_property_value "$properties_file" "simulation-distance")
    
    # 根据服务器类型推荐值
    local max_distance=12
    case "$server_type" in
        "folia") max_distance=8 ;;
        "paper"|"spigot") max_distance=10 ;;
        "forge"|"fabric") max_distance=6 ;;
        *) max_distance=10 ;;
    esac
    
    local new_distance=$(ui_input "请输入模拟距离 (2-$max_distance)

控制实体更新和方块刻的范围，影响性能" "${current_distance:-6}")
    
    if [ $? -eq 0 ] && [ -n "$new_distance" ]; then
        if ! [[ "$new_distance" =~ ^[0-9]+$ ]] || [ "$new_distance" -lt 2 ] || [ "$new_distance" -gt "$max_distance" ]; then
            show_msg "错误" "模拟距离必须在2-$max_distance之间"
            return
        fi
        
        set_property_value "$properties_file" "simulation-distance" "$new_distance"
        show_msg "成功" "模拟距离已设置为: $new_distance"
    fi
}

# 实体优化设置
edit_entity_optimization() {
    local properties_file="$1"
    local server_type="$2"
    
    # 这个功能需要服务器支持相关设置
    # 对于Paper服务器，可以设置一些优化选项
    if [ "$server_type" = "paper" ] || [ "$server_type" = "spigot" ]; then
        show_msg "信息" "实体优化设置需要在Paper配置文件中进行配置。"
        # 这里可以添加打开Paper配置文件的选项
    else
        show_msg "信息" "实体优化功能需要Paper或Spigot服务器支持。"
    fi
}

# 区块加载优化
edit_chunk_loading_optimization() {
    local properties_file="$1"
    local server_type="$2"
    
    # 这个功能主要针对Paper服务器
    if [ "$server_type" = "paper" ] || [ "$server_type" = "spigot" ]; then
        show_msg "信息" "区块加载优化设置需要在Paper配置文件中进行配置。"
    else
        show_msg "信息" "区块加载优化功能需要Paper或Spigot服务器支持。"
    fi
}

# 世界设置编辑
edit_world_settings() {
    local server_name="$1"
    local properties_file="$2"
    local server_type="$3"
    
    while true; do
        # 读取当前值
        local level_type=$(get_property_value "$properties_file" "level-type")
        local generator_settings=$(get_property_value "$properties_file" "generator-settings")
        local spawn_protection=$(get_property_value "$properties_file" "spawn-protection")
        local max_build_height=$(get_property_value "$properties_file" "max-build-height")
        
        choice=$(safe_whiptail --nocancel --clear \
            --title "世界生成设置: $server_name" \
            --menu "当前设置:\n世界类型: ${level_type:-DEFAULT} | 生成设置: ${generator_settings:-默认}\n出生点保护: ${spawn_protection:-16} | 建筑高度: ${max_build_height:-256}\n\n请选择要修改的设置：" 20 70 10 \
            "1" "世界类型 (当前: ${level_type:-DEFAULT})" \
            "2" "世界生成器设置" \
            "3" "出生点保护范围 (当前: ${spawn_protection:-16})" \
            "4" "最大建筑高度 (当前: ${max_build_height:-256})" \
            "5" "种子设置" \
            "0" "返回配置菜单" \
            3>&1 1>&2 2>&3)
        
        case $choice in
            1) edit_level_type_setting "$properties_file" ;;
            2) edit_generator_settings "$properties_file" ;;
            3) edit_spawn_protection_setting "$properties_file" ;;
            4) edit_max_build_height_setting "$properties_file" "$server_type" ;;
            5) edit_seed_setting "$properties_file" ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 编辑世界类型
edit_level_type_setting() {
    local properties_file="$1"
    local current_type=$(get_property_value "$properties_file" "level-type")

    if [ "$NO_GUI" = "true" ]; then
        type_choice=$(cli_menu_select "选择世界类型" \
            "DEFAULT:标准世界 (默认)" \
            "FLAT:超平坦世界" \
            "LARGEBIOMES:巨型生物群系" \
            "AMPLIFIED:放大化世界" \
            "CUSTOMIZED:自定义世界")
    else
        type_choice=$(safe_whiptail --menu "选择世界类型:" 15 50 6 \
            "DEFAULT" "标准世界 (默认)" \
            "FLAT" "超平坦世界" \
            "LARGEBIOMES" "巨型生物群系" \
            "AMPLIFIED" "放大化世界" \
            "CUSTOMIZED" "自定义世界" \
            3>&1 1>&2 2>&3)
    fi

    if [ $? -eq 0 ] && [ -n "$type_choice" ]; then
        set_property_value "$properties_file" "level-type" "$type_choice"
        show_msg "成功" "世界类型已设置为: $type_choice"
    fi
}

# 编辑生成器设置
edit_generator_settings() {
    local properties_file="$1"
    local current_settings=$(get_property_value "$properties_file" "generator-settings")
    
    local new_settings=$(ui_input "请输入生成器设置 (JSON格式)

留空使用默认设置" "$current_settings")
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "generator-settings" "$new_settings"
        show_msg "成功" "生成器设置已更新"
    fi
}

# 编辑出生点保护
edit_spawn_protection_setting() {
    local properties_file="$1"
    local current_protection=$(get_property_value "$properties_file" "spawn-protection")
    
    local new_protection=$(ui_input "请输入出生点保护半径 (区块)

0=禁用保护，16=默认保护范围" "${current_protection:-16}")
    
    if [ $? -eq 0 ] && [ -n "$new_protection" ]; then
        if ! [[ "$new_protection" =~ ^[0-9]+$ ]] || [ "$new_protection" -lt 0 ] || [ "$new_protection" -gt 64 ]; then
            show_msg "错误" "保护半径必须在0-64之间"
            return
        fi
        
        set_property_value "$properties_file" "spawn-protection" "$new_protection"
        show_msg "成功" "出生点保护半径已设置为: $new_protection"
    fi
}

# 编辑最大建筑高度
edit_max_build_height_setting() {
    local properties_file="$1"
    local server_type="$2"
    local current_height=$(get_property_value "$properties_file" "max-build-height")
    
    # 根据版本设置默认值
    local default_height="256"
    local max_height="320"
    
    # 检查Minecraft版本
    local server_info=$(jq -r --arg name "$1" '.servers[] | select(.name == $1)' "$CONFIG_FILE")
    local mc_version=$(echo "$server_info" | jq -r '.version')
    local major_version=$(echo "$mc_version" | awk -F. '{print $1}')
    local minor_version=$(echo "$mc_version" | awk -F. '{print $2}')
    
    if [ "$major_version" -eq 1 ] && [ "$minor_version" -ge 18 ]; then
        default_height="320"
        max_height="320"
    fi
    
    local new_height=$(ui_input "请输入最大建筑高度 (64-$max_height)" "${current_height:-$default_height}")
    
    if [ $? -eq 0 ] && [ -n "$new_height" ]; then
        if ! [[ "$new_height" =~ ^[0-9]+$ ]] || [ "$new_height" -lt 64 ] || [ "$new_height" -gt "$max_height" ]; then
            show_msg "错误" "建筑高度必须在64-$max_height之间"
            return
        fi
        
        set_property_value "$properties_file" "max-build-height" "$new_height"
        show_msg "成功" "最大建筑高度已设置为: $new_height"
    fi
}

# 编辑种子设置
edit_seed_setting() {
    local properties_file="$1"
    local current_seed=$(get_property_value "$properties_file" "level-seed")
    
    local new_seed=$(ui_input "请输入世界种子

留空使用随机种子" "$current_seed")
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "level-seed" "$new_seed"
        show_msg "成功" "世界种子已设置为: ${new_seed:-随机}"
    fi
}

# 安全设置编辑
edit_security_settings() {
    local server_name="$1"
    local properties_file="$2"
    local server_type="$3"
    
    while true; do
        # 读取当前值
        local online_mode=$(get_property_value "$properties_file" "online-mode")
        local white_list=$(get_property_value "$properties_file" "white-list")
        local enforce_whitelist=$(get_property_value "$properties_file" "enforce-whitelist")
        local enable_rcon=$(get_property_value "$properties_file" "enable-rcon")
        
        choice=$(safe_whiptail --nocancel --clear \
            --title "安全设置: $server_name" \
            --menu "当前设置:\n在线验证: ${online_mode:-true} | 白名单: ${white_list:-false}\n强制白名单: ${enforce_whitelist:-false} | RCON: ${enable_rcon:-false}\n\n请选择要修改的设置：" 20 70 10 \
            "1" "在线验证模式 (当前: ${online_mode:-true})" \
            "2" "白名单设置 (当前: ${white_list:-false})" \
            "3" "强制白名单 (当前: ${enforce_whitelist:-false})" \
            "4" "RCON远程控制 (当前: ${enable_rcon:-false})" \
            "5" "操作权限级别" \
            "0" "返回配置菜单" \
            3>&1 1>&2 2>&3)
        
        case $choice in
            1) edit_online_mode_setting "$properties_file" ;;
            2) edit_whitelist_setting "$properties_file" ;;
            3) edit_enforce_whitelist_setting "$properties_file" ;;
            4) edit_rcon_setting "$properties_file" ;;
            5) edit_op_permission_setting "$properties_file" ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 编辑强制白名单设置
edit_enforce_whitelist_setting() {
    local properties_file="$1"
    local current_setting=$(get_property_value "$properties_file" "enforce-whitelist")
    
    ui_confirm "是否强制启用白名单？\n\n启用后服务器会自动重新加载白名单。"
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "enforce-whitelist" "true"
        show_msg "成功" "已启用强制白名单"
    else
        set_property_value "$properties_file" "enforce-whitelist" "false"
        show_msg "成功" "已禁用强制白名单"
    fi
}

# 编辑RCON设置
edit_rcon_setting() {
    local properties_file="$1"
    local current_enable=$(get_property_value "$properties_file" "enable-rcon")
    local current_port=$(get_property_value "$properties_file" "rcon.port")
    local current_password=$(get_property_value "$properties_file" "rcon.password")
    
    ui_confirm "是否启用RCON远程控制？\n\n启用后可以通过网络远程控制服务器。"
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "enable-rcon" "true"
        
        # 设置RCON端口
        local new_port=$(ui_input "请输入RCON端口 (25575-65535)" "${current_port:-25575}")
        if [ $? -eq 0 ] && [ -n "$new_port" ]; then
            set_property_value "$properties_file" "rcon.port" "$new_port"
        fi
        
        # 设置RCON密码
        local new_password=$(ui_input "请输入RCON密码" "$current_password")
        if [ $? -eq 0 ] && [ -n "$new_password" ]; then
            set_property_value "$properties_file" "rcon.password" "$new_password"
        fi
        
        show_msg "成功" "RCON已启用，端口: ${new_port:-25575}"
    else
        set_property_value "$properties_file" "enable-rcon" "false"
        show_msg "成功" "RCON已禁用"
    fi
}

# 编辑操作权限级别
edit_op_permission_setting() {
    local properties_file="$1"
    local current_level=$(get_property_value "$properties_file" "op-permission-level")

    if [ "$NO_GUI" = "true" ]; then
        level_choice=$(cli_menu_select "选择OP权限级别" \
            "1:级别1: 基本命令 (默认)" \
            "2:级别2: 中级命令" \
            "3:级别3: 高级命令" \
            "4:级别4: 所有命令 (包括控制台)")
    else
        level_choice=$(safe_whiptail --menu "选择OP权限级别:" 15 50 4 \
            "1" "级别1: 基本命令 (默认)" \
            "2" "级别2: 中级命令" \
            "3" "级别3: 高级命令" \
            "4" "级别4: 所有命令 (包括控制台)" \
            3>&1 1>&2 2>&3)
    fi

    if [ $? -eq 0 ] && [ -n "$level_choice" ]; then
        set_property_value "$properties_file" "op-permission-level" "$level_choice"
        show_msg "成功" "OP权限级别已设置为: $level_choice"
    fi
}

# 查看所有配置项
view_all_properties() {
    local server_name="$1"
    local properties_file="$2"
    
    if [ ! -f "$properties_file" ]; then
        show_msg "错误" "配置文件不存在"
        return
    fi
    
    # 创建临时文件显示所有配置
    local temp_file=$(mktemp)
    
    # 显示非注释的配置项
    echo "=== $server_name 服务器配置 ===" > "$temp_file"
    echo "文件路径: $properties_file" >> "$temp_file"
    echo "生成时间: $(date)" >> "$temp_file"
    echo "==========================================" >> "$temp_file"
    echo "" >> "$temp_file"
    
    # 显示所有配置项（排除注释和空行）
    grep -v "^#" "$properties_file" | grep -v "^$" >> "$temp_file"
    
    # 使用less查看文件
    safe_edit_file "$temp_file" "$server_name"
    
    # 清理临时文件
    rm -f "$temp_file"
}

# 世界设置编辑函数补全
edit_world_settings() {
    local server_name="$1"
    local properties_file="$2"
    local server_type="$3"
    
    while true; do
        # 读取当前值
        local level_type=$(get_property_value "$properties_file" "level-type")
        local generator_settings=$(get_property_value "$properties_file" "generator-settings")
        local spawn_protection=$(get_property_value "$properties_file" "spawn-protection")
        local max_build_height=$(get_property_value "$properties_file" "max-build-height")
        local level_seed=$(get_property_value "$properties_file" "level-seed")
        
        choice=$(safe_whiptail --nocancel --clear \
            --title "世界生成设置: $server_name" \
            --menu "当前设置:\n世界类型: ${level_type:-DEFAULT}\n出生点保护: ${spawn_protection:-16}\n建筑高度: ${max_build_height:-256}\n世界种子: ${level_seed:-随机}\n\n请选择要修改的设置：" 20 70 10 \
            "1" "世界类型 (当前: ${level_type:-DEFAULT})" \
            "2" "世界生成器设置" \
            "3" "出生点保护范围 (当前: ${spawn_protection:-16})" \
            "4" "最大建筑高度 (当前: ${max_build_height:-256})" \
            "5" "世界种子设置 (当前: ${level_seed:-随机})" \
            "6" "资源包设置" \
            "0" "返回配置菜单" \
            3>&1 1>&2 2>&3)
        
        case $choice in
            1) edit_level_type_setting "$properties_file" ;;
            2) edit_generator_settings "$properties_file" ;;
            3) edit_spawn_protection_setting "$properties_file" ;;
            4) edit_max_build_height_setting "$properties_file" "$server_type" ;;
            5) edit_seed_setting "$properties_file" ;;
            6) edit_resource_pack_settings "$properties_file" ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 编辑资源包设置
edit_resource_pack_settings() {
    local properties_file="$1"
    local current_pack=$(get_property_value "$properties_file" "resource-pack")
    local current_hash=$(get_property_value "$properties_file" "resource-pack-hash")

    if [ "$NO_GUI" = "true" ]; then
        choice=$(cli_menu_select "资源包设置" \
            "1:设置资源包URL" \
            "2:设置资源包哈希" \
            "3:清除资源包设置" \
            "0:返回")
    else
        choice=$(safe_whiptail --menu "资源包设置:" 15 60 4 \
            "1" "设置资源包URL" \
            "2" "设置资源包哈希" \
            "3" "清除资源包设置" \
            "0" "返回" \
            3>&1 1>&2 2>&3)
    fi
    
    case $choice in
        1)
            local new_url=$(ui_input "请输入资源包下载URL" "$current_pack")
            if [ $? -eq 0 ]; then
                set_property_value "$properties_file" "resource-pack" "$new_url"
                show_msg "成功" "资源包URL已设置"
            fi
            ;;
        2)
            local new_hash=$(ui_input "请输入资源包SHA-1哈希值" "$current_hash")
            if [ $? -eq 0 ]; then
                set_property_value "$properties_file" "resource-pack-hash" "$new_hash"
                show_msg "成功" "资源包哈希已设置"
            fi
            ;;
        3)
            ui_confirm "确定要清除资源包设置吗？"
            if [ $? -eq 0 ]; then
                set_property_value "$properties_file" "resource-pack" ""
                set_property_value "$properties_file" "resource-pack-hash" ""
                show_msg "成功" "资源包设置已清除"
            fi
            ;;
        0) return ;;
    esac
}

# 高级安全设置
edit_security_settings() {
    local server_name="$1"
    local properties_file="$2"
    local server_type="$3"
    
    while true; do
        # 读取当前安全设置
        local online_mode=$(get_property_value "$properties_file" "online-mode")
        local white_list=$(get_property_value "$properties_file" "white-list")
        local enforce_whitelist=$(get_property_value "$properties_file" "enforce-whitelist")
        local enable_rcon=$(get_property_value "$properties_file" "enable-rcon")
        local op_permission=$(get_property_value "$properties_file" "op-permission-level")
        local snooper_enabled=$(get_property_value "$properties_file" "snooper-enabled")
        
        choice=$(safe_whiptail --nocancel --clear \
            --title "高级安全设置: $server_name" \
            --menu "当前设置:\n在线验证: ${online_mode:-true}\n白名单: ${white_list:-false}\n强制白名单: ${enforce_whitelist:-false}\nRCON: ${enable_rcon:-false}\nOP权限: ${op_permission:-4}\n数据收集: ${snooper_enabled:-true}\n\n请选择要修改的设置：" 22 70 12 \
            "1" "在线验证模式 (当前: ${online_mode:-true})" \
            "2" "白名单设置 (当前: ${white_list:-false})" \
            "3" "强制白名单 (当前: ${enforce_whitelist:-false})" \
            "4" "RCON远程控制 (当前: ${enable_rcon:-false})" \
            "5" "OP权限级别 (当前: ${op_permission:-4})" \
            "6" "数据收集设置 (当前: ${snooper_enabled:-true})" \
            "7" "查询服务设置" \
            "0" "返回配置菜单" \
            3>&1 1>&2 2>&3)
        
        case $choice in
            1) edit_online_mode_setting "$properties_file" ;;
            2) edit_whitelist_setting "$properties_file" ;;
            3) edit_enforce_whitelist_setting "$properties_file" ;;
            4) edit_rcon_setting "$properties_file" ;;
            5) edit_op_permission_setting "$properties_file" ;;
            6) edit_snooper_setting "$properties_file" ;;
            7) edit_query_settings "$properties_file" ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 编辑数据收集设置
edit_snooper_setting() {
    local properties_file="$1"
    local current_setting=$(get_property_value "$properties_file" "snooper-enabled")
    
    ui_confirm "是否允许向Mojang发送统计数据？\n\n这有助于Mojang改进游戏，但会发送服务器信息。"
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "snooper-enabled" "true"
        show_msg "成功" "已启用数据收集"
    else
        set_property_value "$properties_file" "snooper-enabled" "false"
        show_msg "成功" "已禁用数据收集"
    fi
}

# 编辑查询服务设置
edit_query_settings() {
    local properties_file="$1"
    local current_enable=$(get_property_value "$properties_file" "enable-query")
    local current_port=$(get_property_value "$properties_file" "query.port")
    
    ui_confirm "是否启用查询服务？\n\n启用后可以通过UDP查询服务器状态信息。"
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "enable-query" "true"
        
        # 设置查询端口
        local new_port=$(ui_input "请输入查询服务端口 (默认25565)" "${current_port:-25565}")
        if [ $? -eq 0 ] && [ -n "$new_port" ]; then
            set_property_value "$properties_file" "query.port" "$new_port"
        fi
        
        show_msg "成功" "查询服务已启用"
    else
        set_property_value "$properties_file" "enable-query" "false"
        show_msg "成功" "查询服务已禁用"
    fi
}

# 性能优化设置补全
edit_performance_settings() {
    local server_name="$1"
    local properties_file="$2"
    local server_type="$3"
    
    while true; do
        # 读取当前性能设置
        local max_tick_time=$(get_property_value "$properties_file" "max-tick-time")
        local max_world_size=$(get_property_value "$properties_file" "max-world-size")
        local simulation_distance=$(get_property_value "$properties_file" "simulation-distance")
        local view_distance=$(get_property_value "$properties_file" "view-distance")
        local network_compression=$(get_property_value "$properties_file" "network-compression-threshold")
        
        choice=$(safe_whiptail --nocancel --clear \
            --title "性能优化设置: $server_name" \
            --menu "当前设置:\n最大tick时间: ${max_tick_time:-60000}ms\n世界大小: ${max_world_size:-29999984}\n模拟距离: ${simulation_distance:-10}\n视距: ${view_distance:-10}\n网络压缩: ${network_compression:-256}\n\n请选择要修改的设置：" 22 70 12 \
            "1" "最大tick时间 (当前: ${max_tick_time:-60000}ms)" \
            "2" "世界大小限制 (当前: ${max_world_size:-29999984})" \
            "3" "模拟距离 (当前: ${simulation_distance:-10})" \
            "4" "视距设置 (当前: ${view_distance:-10})" \
            "5" "网络压缩阈值 (当前: ${network_compression:-256})" \
            "6" "实体相关优化" \
            "7" "区块加载优化" \
            "8" "内存和GC优化" \
            "0" "返回配置菜单" \
            3>&1 1>&2 2>&3)
        
        case $choice in
            1) edit_max_tick_time_setting "$properties_file" "$server_type" ;;
            2) edit_max_world_size_setting "$properties_file" ;;
            3) edit_simulation_distance_setting "$properties_file" "$server_type" ;;
            4) edit_view_distance_setting "$properties_file" "$server_type" ;;
            5) edit_network_compression_setting "$properties_file" "$server_type" ;;
            6) edit_entity_optimization_settings "$properties_file" "$server_type" ;;
            7) edit_chunk_loading_settings "$properties_file" "$server_type" ;;
            8) edit_memory_gc_settings "$properties_name" "$server_type" ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 实体优化设置
edit_entity_optimization_settings() {
    local properties_file="$1"
    local server_type="$2"
    
    # 显示实体优化选项（主要针对Paper服务器）
    if [ "$server_type" = "paper" ] || [ "$server_type" = "spigot" ]; then
        ui_message "实体优化" "实体优化设置需要在Paper配置文件中进行。\n\n请使用文件与配置功能编辑 paper.yml 或 spigot.yml 文件。"
    else
        show_msg "信息" "实体优化功能需要Paper或Spigot服务器支持。\n\n当前服务器类型: $server_type"
    fi
}

# 区块加载优化设置
edit_chunk_loading_settings() {
    local properties_file="$1"
    local server_type="$2"
    
    # 显示区块加载优化选项
    if [ "$server_type" = "paper" ] || [ "$server_type" = "spigot" ]; then
        ui_message "区块加载优化" "区块加载优化设置需要在Paper配置文件中进行。\n\n请使用文件与配置功能编辑 paper.yml 文件中的区块设置。"
    else
        show_msg "信息" "区块加载优化功能需要Paper服务器支持。\n\n当前服务器类型: $server_type"
    fi
}

# 内存和GC优化设置
edit_memory_gc_settings() {
    local server_name="$1"
    local server_type="$2"
    
    # 显示内存优化建议
    local message="内存和GC优化建议:\n\n"
    message+="1. 调整启动脚本中的内存参数 (-Xmx, -Xms)\n"
    message+="2. 使用合适的GC算法\n"
    message+="3. 根据服务器类型选择优化策略\n\n"
    message+="当前服务器: $server_name ($server_type)"
    
    ui_message "内存优化建议" "$message"
}

# 配置文件验证函数
validate_server_properties() {
    local properties_file="$1"
    
    if [ ! -f "$properties_file" ]; then
        echo "错误: 配置文件不存在"
        return 1
    fi
    
    # 检查关键配置项
    local errors=0
    local warnings=0
    
    # 检查端口设置
    local port=$(get_property_value "$properties_file" "server-port")
    if ! [[ "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1024 ] || [ "$port" -gt 65535 ]; then
        echo "警告: 服务器端口 $port 可能无效"
        ((warnings++))
    fi
    
    # 检查视距设置
    local view_distance=$(get_property_value "$properties_file" "view-distance")
    if ! [[ "$view_distance" =~ ^[0-9]+$ ]] || [ "$view_distance" -lt 2 ] || [ "$view_distance" -gt 32 ]; then
        echo "警告: 视距 $view_distance 可能影响性能"
        ((warnings++))
    fi
    
    # 检查在线模式
    local online_mode=$(get_property_value "$properties_file" "online-mode")
    if [ "$online_mode" = "false" ]; then
        echo "警告: 在线验证已禁用，可能存在安全风险"
        ((warnings++))
    fi
    
    if [ $errors -eq 0 ] && [ $warnings -eq 0 ]; then
        echo "配置验证通过"
        return 0
    else
        echo "配置验证完成: $errors 个错误, $warnings 个警告"
        return 1
    fi
}

# 配置文件备份功能
backup_server_properties() {
    local properties_file="$1"
    local server_name="$2"
    
    local backup_dir="$MCSERVER_DIR/$server_name/backups"
    mkdir -p "$backup_dir"
    
    local backup_file="$backup_dir/server.properties.$(date +%Y%m%d_%H%M%S).backup"
    cp "$properties_file" "$backup_file"
    
    if [ $? -eq 0 ]; then
        echo "配置已备份到: $(basename "$backup_file")"
        return 0
    else
        echo "错误: 配置备份失败"
        return 1
    fi
}

# 重新生成启动脚本时更新Java版本
regenerate_start_script() {
    local server_name=$1
    local server_dir="$MCSERVER_DIR/$server_name"
    
    # 获取服务器信息
    local server_info=$(jq -r --arg name "$server_name" '.servers[] | select(.name == $name)' "$CONFIG_FILE")
    local server_type=$(echo "$server_info" | jq -r '.type')
    local mc_version=$(echo "$server_info" | jq -r '.version')
    
    # 获取当前Java版本配置
    local current_jdk=""
    if [ -f "$server_dir/java_version.cfg" ]; then
        source "$server_dir/java_version.cfg"
        current_jdk="$JDK_VERSION"
    fi
    
    # 备份原启动脚本
    if [ -f "$server_dir/start.sh" ]; then
        cp "$server_dir/start.sh" "$server_dir/start.sh.backup.$(date +%Y%m%d_%H%M%S)"
    fi
    
    # 重新生成启动脚本
    create_start_script "$server_dir" "$server_type" "$mc_version" "$current_jdk"
    
    if [ $? -eq 0 ]; then
        show_msg "成功" "启动脚本已重新生成并更新Java配置"
    else
        show_msg "错误" "启动脚本生成失败"
    fi
}

# 服务器文件操作功能

# 编辑服务器文件
edit_server_file() {
    local server_name="$1"
    local server_dir="$MCSERVER_DIR/$server_name"
    
    # 获取服务器目录下的所有配置文件
    local files=()
    while IFS= read -r -d '' file; do
        if [ -f "$file" ]; then
            local filename=$(basename "$file")
            # 排除二进制文件和大文件
            if [[ "$filename" != *".jar" ]] && [[ "$filename" != *".zip" ]] && \
               [[ "$filename" != *".tar.gz" ]] && [[ "$filename" != *".log" ]] && \
               [[ "$(file -b --mime-type "$file")" == text/* ]]; then
                local size=$(du -h "$file" | cut -f1)
                files+=("$filename" "$size")
            fi
        fi
    done < <(find "$server_dir" -maxdepth 1 -type f -print0 2>/dev/null)
    
    if [ ${#files[@]} -eq 0 ]; then
        show_msg "信息" "没有找到可编辑的文本文件"
        return
    fi

    # 选择文件
    if [ "$NO_GUI" = "true" ]; then
        selected=$(cli_menu_select "选择要编辑的文件" "${files[@]}")
    else
        selected=$(safe_whiptail --menu "选择要编辑的文件：" 20 60 10 "${files[@]}" 3>&1 1>&2 2>&3)
    fi
    if [ -z "$selected" ]; then
        return
    fi
    
    local file_path="$server_dir/$selected"
    
    # 检查文件大小（避免编辑大文件）
    local file_size=$(stat -c%s "$file_path" 2>/dev/null || echo 0)
    if [ "$file_size" -gt 1048576 ]; then # 1MB
        ui_confirm "文件较大 ($(du -h "$file_path" | cut -f1))，可能不适合编辑。是否继续？"
        if [ $? -ne 0 ]; then
            return
        fi
    fi
    
    # 使用安全的文件编辑函数
    if safe_edit_file "$file_path" "$server_name"; then
        show_msg "成功" "文件编辑完成"
    else
        show_msg "错误" "文件编辑失败"
    fi
}

# 列出服务器文件
list_server_files() {
    local server_name="$1"
    local current_path="$MCSERVER_DIR/$server_name"

    # 确保起始路径存在
    if [ ! -d "$current_path" ]; then
        show_msg "错误" "服务器目录不存在: $current_path"
        return 1
    fi

    while true; do
        # 构建菜单项
        local menu_items=()
        menu_items+=(".." "返回上级目录")

        # 添加子目录
        while IFS= read -r -d '' dir; do
            local dirname=$(basename "$dir")
            menu_items+=("$dirname/" "目录")
        done < <(find "$current_path" -maxdepth 1 -type d ! -name "$(basename "$current_path")" -print0 2>/dev/null | sort -z)

        # 添加可编辑的文本文件（排除二进制/大文件）
        while IFS= read -r -d '' file; do
            local filename=$(basename "$file")
            # 跳过已知二进制或日志类文件
            if [[ "$filename" == *.jar ]] || [[ "$filename" == *.zip ]] || \
               [[ "$filename" == *.tar.* ]] || [[ "$filename" == *.log ]] || \
               [[ "$filename" == eula.txt ]]; then
                continue
            fi
            # 检查是否为文本文件且小于1MB
            if [[ "$(file -b --mime-type "$file")" == text/* ]] && \
               [ "$(stat -c%s "$file" 2>/dev/null || echo 0)" -le 1048576 ]; then
                local size=$(du -h "$file" | cut -f1)
                menu_items+=("$filename" "文件 ($size)")
            fi
        done < <(find "$current_path" -maxdepth 1 -type f -print0 2>/dev/null | sort -z)

        # 如果当前不在服务器根目录，显示当前路径
        local display_title="浏览: $(basename "$current_path")"
        if [ "$current_path" != "$MCSERVER_DIR/$server_name" ]; then
            display_title+=" (当前: ${current_path#$MCSERVER_DIR/$server_name/})"
        fi

        # 显示菜单
        local choice=$(safe_whiptail --nocancel --clear \
            --title "文件与配置 - $server_name" \
            --menu "$display_title" 20 70 12 "${menu_items[@]}" \
            3>&1 1>&2 2>&3)

        [ $? -ne 0 ] && return

        if [ "$choice" = ".." ]; then
            # 返回上级
            if [ "$current_path" = "$MCSERVER_DIR/$server_name" ]; then
                # 已在根目录，退出浏览
                return
            else
                current_path=$(dirname "$current_path")
            fi
        elif [[ "$choice" == */ ]]; then
            # 进入子目录
            current_path="$current_path/${choice%/}"
        else
            # 编辑选定文件
            local file_path="$current_path/$choice"
            if [ -f "$file_path" ]; then
                safe_edit_file "$file_path" "$server_name"
                # 编辑完成后**不跳转菜单**，继续留在当前文件列表
            fi
        fi
    done
}

# 子目录浏览函数
list_server_files_subdir() {
    local server_name="$1"
    local subdir="$2"
    local server_dir="$MCSERVER_DIR/$server_name"
    local current_dir="$server_dir/$subdir"
    
    while true; do
        local files=()
        files+=(".." "返回上级")
        
        # 获取当前目录内容
        while IFS= read -r -d '' item; do
            local item_name=$(basename "$item")
            if [ -d "$item" ]; then
                local file_count=$(find "$item" -maxdepth 1 -type f | wc -l)
                files+=("$item_name/" "目录 - ${file_count}文件")
            elif [ -f "$item" ]; then
                local size=$(du -h "$item" | cut -f1)
                local mtime=$(stat -c "%y" "$item" | cut -d. -f1)
                files+=("$item_name" "$size - $mtime")
            fi
        done < <(find "$current_dir" -maxdepth 1 -print0 2>/dev/null | sort -z)
        
        selected=$(safe_whiptail --title "文件与配置: $server_name/$subdir" \
            --menu "当前目录: $current_dir\n选择文件或目录：" \
            25 80 15 "${files[@]}" 3>&1 1>&2 2>&3)
            
        if [ -z "$selected" ]; then
            return
        fi
        
        if [ "$selected" = ".." ]; then
            return
        fi
        
        local selected_path="$current_dir/$selected"
        
        if [ -d "$selected_path" ]; then
            # 进入子目录
            list_server_files_subdir "$server_name" "$subdir/$selected"
        else
            # 文件操作
            file_operations_menu "$server_name" "$subdir/$selected"
            return
        fi
    done
}

# 显示目录内容
show_directory_contents() {
    local server_name="$1"
    local dir_name="$2"
    local server_dir="$MCSERVER_DIR/$server_name"
    local dir_path="$server_dir/$dir_name"
    
    local files=()
    while IFS= read -r -d '' file; do
        if [ -f "$file" ]; then
            local filename=$(basename "$file")
            local size=$(du -h "$file" | cut -f1)
            files+=("$filename" "$size")
        elif [ -d "$file" ]; then
            local dirname=$(basename "$file")
            files+=("$dirname/" "目录")
        fi
    done < <(find "$dir_path" -maxdepth 1 -print0)

    if [ "$NO_GUI" = "true" ]; then
        cli_menu_select "目录内容: $dir_name" "${files[@]}"
    else
        safe_whiptail --title "目录内容: $dir_name" --menu "选择文件：" 20 60 10 "${files[@]}" 3>&1 1>&2 2>&3
    fi
}

# 文件操作菜单
file_operations_menu() {
    local server_name="$1"
    local filename="$2"
    local server_dir="$MCSERVER_DIR/$server_name"
    local file_path="$server_dir/$filename"
    
    while true; do
        choice=$(safe_whiptail --nocancel --clear \
            --title "文件操作: $filename" \
            --menu "请选择操作：" 15 50 5 \
            "1" "查看内容" \
            "2" "编辑文件" \
            "3" "删除文件" \
            "0" "返回" \
            3>&1 1>&2 2>&3)
        
        case $choice in
            1) view_file_content "$server_name" "$filename" ;;
            2) edit_server_file_specific "$server_name" "$filename" ;;
            3) delete_specific_file "$server_name" "$filename" ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 查看文件内容
view_file_content() {
    local server_name="$1"
    local filename="$2"
    local server_dir="$MCSERVER_DIR/$server_name"
    local file_path="$server_dir/$filename"
    
    if [ ! -f "$file_path" ]; then
        show_msg "错误" "文件不存在"
        return
    fi
    
    # 设置日志查看模式标记
    export IN_LOG_VIEW_MODE="true"
    export CURRENT_SERVER="$server_name"
    
    # 保存当前终端设置
    save_terminal_settings
    
    # 结束图形界面，恢复终端
    exec 3>&-
    exec 4>&-
    clear
    
    echo -e "${BLUE}正在查看文件: $filename${NC}"
    echo -e "${YELLOW}使用方向键浏览，按 'q' 键返回${NC}"
    echo -e "${YELLOW}按 Ctrl+C 可以取消查看${NC}"
    echo -e "${YELLOW}按任意键继续...${NC}"
    read -n 1 -s
    
    # 使用less查看文件内容
    if command -v less >/dev/null 2>&1; then
        if ! less -R "$file_path"; then
            echo -e "${YELLOW}less 命令异常，使用 cat 显示内容...${NC}"
            cat "$file_path"
            echo -e "${YELLOW}按任意键返回...${NC}"
            read -n 1 -s
        fi
    else
        # 如果less不可用，直接输出内容
        cat "$file_path"
        echo -e "${YELLOW}按任意键返回...${NC}"
        read -n 1 -s
    fi
    
    # 查看完成后重新启动管理器以恢复图形界面
    echo -e "${GREEN}返回管理器...${NC}"
    sleep 1
    
    # 恢复设置
    restore_terminal_settings
    export IN_LOG_VIEW_MODE="false"
    export CURRENT_SERVER=""
    
    # 重新启动管理器，返回正确的菜单
    if [ -n "$server_name" ]; then
        exec "$SCRIPT_PATH" --skip-welcome --goto-menu "server_management" -n "$server_name"
    else
        exec "$SCRIPT_PATH" --skip-welcome
    fi
}

# 编辑特定文件
edit_server_file_specific() {
    local server_name="$1"
    local filename="$2"
    local server_dir="$MCSERVER_DIR/$server_name"
    local file_path="$server_dir/$filename"
    
    if [ ! -f "$file_path" ]; then
        show_msg "错误" "文件不存在: $filename"
        return 1
    fi
    
    # 检查文件大小
    local file_size=$(stat -c%s "$file_path" 2>/dev/null || echo 0)
    if [ "$file_size" -gt 1048576 ]; then
        ui_confirm "文件较大 ($(du -h "$file_path" | cut -f1))，可能不适合编辑。是否继续？"
        if [ $? -ne 0 ]; then
            return
        fi
    fi
    
    # 使用安全的文件编辑函数
    if safe_edit_file "$file_path" "$server_name"; then
        show_msg "成功" "文件 $filename 编辑完成"
    else
        show_msg "错误" "文件编辑失败"
    fi
}

# 删除特定文件
delete_specific_file() {
    local server_name="$1"
    local filename="$2"
    local server_dir="$MCSERVER_DIR/$server_name"
    local file_path="$server_dir/$filename"
    
    # 确认删除
    ui_confirm "确定要删除文件 '$filename' 吗？"
    if [ $? -ne 0 ]; then
        return
    fi
    
    # 防止删除核心文件
    local server_jar=$(detect_server_jar "$server_dir")
    if [ "$filename" = "$server_jar" ]; then
        show_msg "错误" "不能删除服务器核心文件"
        return
    fi
    
    # 删除文件
    if rm -f "$file_path"; then
        show_msg "成功" "文件 $filename 已删除"
    else
        show_msg "错误" "文件删除失败"
    fi
}

# 查看服务器核心信息
show_server_core_info() {
    local server_name="$1"
    local server_dir="$MCSERVER_DIR/$server_name"
    
    local server_jar=$(detect_server_jar "$server_dir")
    if [ -z "$server_jar" ]; then
        show_msg "错误" "找不到服务器核心文件"
        return
    fi
    
    local info="服务器: $server_name\n"
    info+="核心文件: $server_jar\n"
    info+="文件大小: $(du -h "$server_dir/$server_jar" | cut -f1)\n"
    info+="修改时间: $(stat -c %y "$server_dir/$server_jar" | cut -d. -f1)\n"
    
    # 获取服务器信息
    local server_info=$(jq -r --arg name "$server_name" '.servers[] | select(.name == $name)' "$CONFIG_FILE")
    local server_type=$(echo "$server_info" | jq -r '.type')
    local mc_version=$(echo "$server_info" | jq -r '.version')
    
    info+="服务器类型: $server_type\n"
    info+="Minecraft版本: $mc_version"
    
    # 尝试获取更多文件信息
    if [ -d "$server_dir/mods" ]; then
        local mod_count=$(find "$server_dir/mods" -name "*.jar" | wc -l)
        info+="\n模组数量: $mod_count"
    fi
    
    if [ -d "$server_dir/plugins" ]; then
        local plugin_count=$(find "$server_dir/plugins" -name "*.jar" | wc -l)
        info+="\n插件数量: $plugin_count"
    fi
    
    ui_message "服务器核心信息" "$info"
}


# 删除服务器
delete_server() {
    local server_name="$1"

    # 确认删除（使用 ui_confirm 兼容 CLI/GUI 模式）
    if ! ui_confirm "确定要删除服务器 '$server_name' 吗？此操作不可恢复！"; then
        return 1
    fi

    # 隐藏图形界面
    clear
    echo -e "${BLUE}正在删除服务器 '$server_name'...${NC}"

    # 删除服务器目录
    echo -e "${YELLOW}正在删除服务器文件...${NC}"
    rm -rf "$MCSERVER_DIR/$server_name"

    # 从配置中移除
    remove_server_from_config "$server_name"

    echo -e "${GREEN}服务器已删除${NC}"
    sleep 2
    
    # 删除后直接返回服务器管理菜单
    return 2
}

# 从配置中移除服务器
remove_server_from_config() {
    local server_name="$1"
    local temp_file="$CONFIG_FILE.tmp"
    
    jq --arg name "$server_name" \
       'del(.servers[] | select(.name == $name))' \
       "$CONFIG_FILE" > "$temp_file" && mv "$temp_file" "$CONFIG_FILE"
}

# 服务器检测函数

# 检查服务器是否存在
is_server_exists() {
    local server_name=$1
    
    if [ ! -f "$CONFIG_FILE" ]; then
        return 1
    fi
    
    jq -e --arg name "$server_name" '.servers[] | select(.name == $name)' "$CONFIG_FILE" > /dev/null 2>&1
}

# 检查服务器是否运行
is_server_running() {
    local server_name=$1
    local server_dir="$MCSERVER_DIR/$server_name"
    local pid_file="$server_dir/server.pid"
    
    if [ ! -f "$pid_file" ]; then
        return 1
    fi
    
    local pid=$(cat "$pid_file")
    if ps -p "$pid" > /dev/null 2>&1; then
        return 0
    else
        rm "$pid_file"
        return 1
    fi
}

# 检测实际的服务器核心文件
detect_server_jar() {
    local server_dir=$1

    # 首先检查基岩版服务器
    if [ -f "$server_dir/bedrock_server" ]; then
        echo "bedrock_server"
        return 0
    fi

    # 检查常见的服务器核心文件命名模式
    local possible_jars=(
        "server.jar"
        "*.jar"
        "folia-*.jar"
        "paper-*.jar"
        "spigot-*.jar"
        "bukkit-*.jar"
        "craftbukkit-*.jar"
        "forge-*.jar"
        "neoforged-*.jar"
        "fabric-server-launch.jar"
        "fabric-server-*.jar"
        "quilt-server-*.jar"
        "mohist-*.jar"
        "nukkit-*.jar"
        "spongevanilla-*.jar"
        "spongeforge-*.jar"
        "minecraft_server.*.jar"
        "vanilla-*.jar"
    )

    for pattern in "${possible_jars[@]}"; do
        local jars=$(find "$server_dir" -maxdepth 1 -name "$pattern" -type f ! -name "*.log" ! -name "*.txt" ! -name "*-installer.jar")
        if [ -n "$jars" ]; then
            # 返回第一个找到的jar文件
            echo "$(basename "$(echo "$jars" | head -1)")"
            return 0
        fi
    done

    # 如果没有找到，返回空
    echo ""
}

# 查找合适的Java版本
find_appropriate_java() {
    local mc_version=$1
    
    # 获取推荐的JDK版本
    local recommended_jdk=$(get_recommended_jdk_for_version "$mc_version")
    
    # 检查推荐的JDK是否已安装
    if jdk_exists "$recommended_jdk"; then
        echo "$MCJDK_DIR/jdk$recommended_jdk/bin/java"
        return 0
    fi
    
    # 检查系统Java
    if command -v java >/dev/null 2>&1; then
        local system_java_version=$(java -version 2>&1 | head -1 | grep -o '[0-9._]*' | head -1)
        local system_major=$(echo "$system_java_version" | awk -F. '{print $1}')
        local required_major=$(get_required_jdk_version "$mc_version")
        
        # 检查系统Java是否满足要求
        if [ "$system_major" -ge "$required_major" ]; then
            echo "java"
            return 0
        fi
    fi
    
    # 尝试查找已安装的兼容JDK
    for installed_jdk in $(ls "$MCJDK_DIR" 2>/dev/null | grep '^jdk'); do
        local jdk_ver=${installed_jdk#jdk}
        local required=$(get_required_jdk_version "$mc_version")
        
        if [ "$jdk_ver" -ge "$required" ]; then
            echo "$MCJDK_DIR/$installed_jdk/bin/java"
            return 0
        fi
    done
    
    # 最后尝试使用系统Java
    if command -v java >/dev/null 2>&1; then
        echo "java"
    else
        echo ""
        return 1
    fi
}


# JDK 管理功能

# JDK 管理菜单
jdk_management() {
    # CLI 模式调用 CLI 版本
    if [ "$NO_GUI" = "true" ]; then
        cli_jdk_management
        return
    fi

    while true; do
        choice=$(safe_whiptail --nocancel --clear \
            --title "JDK 管理" \
            --menu "请选择操作：" 16 50 6 \
            "1" "安装JDK" \
            "2" "管理已安装JDK" \
            "3" "自动配置JDK" \
            "4" "更新JDK列表" \
            "5" "管理JDK供应商" \
            "0" "返回主菜单" \
            3>&1 1>&2 2>&3)

        case $choice in
            1) install_jdk ;;
            2) manage_installed_jdks ;;
            3) auto_configure_jdk ;;
            4) update_jdk_list ;;
            5) manage_jdk_providers ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# ============================================
# CLI JDK 管理菜单
# ============================================

cli_jdk_management() {
    while true; do
        # 清屏
        clear 2>/dev/null || printf "\033[2J\033[H"

        echo ""
        echo "============================================"
        echo "           JDK 管理"
        echo "============================================"
        echo ""
        echo "  1) 安装 JDK          - 下载并安装指定版本 JDK"
        echo "  2) 管理已安装的 JDK  - 查看、删除、设为默认"
        echo "  3) 自动配置 JDK      - 为服务器自动配置 JDK"
        echo "  4) 更新 JDK 列表    - 刷新可用 JDK 版本"
        echo "  5) 管理 JDK 供应商   - 设置默认/启用/禁用供应商"
        echo "  0) 返回主菜单"
        echo ""
        echo "--------------------------------------------"

        echo -n "请输入选项编号 [0-5]: "
        read -r choice

        # 处理空输入
        if [ -z "$choice" ]; then
            echo ""
            continue
        fi

        case "$choice" in
            1)
                echo ""
                echo ">>> 进入安装 JDK..."
                echo ""
                cli_install_jdk
                ;;
            2)
                echo ""
                echo ">>> 进入管理 JDK..."
                echo ""
                cli_manage_installed_jdks
                ;;
            3)
                echo ""
                echo ">>> 进入自动配置 JDK..."
                echo ""
                auto_configure_jdk
                ;;
            4)
                echo ""
                echo ">>> 正在更新 JDK 列表..."
                echo ""
                update_jdk_list
                ;;
            5)
                echo ""
                echo ">>> 进入管理 JDK 供应商..."
                echo ""
                cli_manage_jdk_providers
                ;;
            0)
                echo ""
                echo "返回主菜单..."
                echo ""
                break
                ;;
            *)
                echo ""
                echo -e "${RED}无效选项 '$choice'，请重新输入${NC}"
                echo ""
                ;;
        esac
    done
}

# ============================================
# CLI JDK 供应商管理
# ============================================

cli_manage_jdk_providers() {
    while true; do
        # 清屏
        clear 2>/dev/null || printf "\033[2J\033[H"

        echo ""
        echo "============================================"
        echo "        JDK 供应商管理"
        echo "============================================"
        echo ""

        # 显示当前默认供应商（确保有默认值）
        local display_provider="${DEFAULT_PROVIDER:-adoptium}"
        echo -e "  ${CYAN}当前默认供应商: ${GREEN}${display_provider}${NC} (${JDK_PROVIDERS[$display_provider]:-Unknown})"
        echo ""

        # 显示所有供应商列表
        local index=1
        for provider in adoptium liberica corretto zulu openjdk; do
            local enabled="true"
            if command -v jq &>/dev/null && [ -f "$CONFIG_FILE" ]; then
                enabled=$(jq -r ".providers.enabled.$provider // true" "$CONFIG_FILE" 2>/dev/null)
            fi
            local status="${GREEN}✓ 启用${NC}"
            local default_mark=""

            if [ "$enabled" = "false" ]; then
                status="${RED}✗ 禁用${NC}"
            fi

            if [ "$provider" = "$DEFAULT_PROVIDER" ]; then
                default_mark="${YELLOW} [默认]${NC}"
            fi

            echo -e "  $index) ${JDK_PROVIDERS[$provider]}$default_mark - $status"
            echo "      支持版本: ${PROVIDER_VERSIONS[$provider]}"
            echo "      特性: ${PROVIDER_FEATURES[$provider]}"
            echo ""
            index=$((index + 1))
        done

        echo "--------------------------------------------"
        echo "  6) 设置默认供应商"
        echo "  7) 启用/禁用供应商"
        echo "  8) 查看供应商详情"
        echo "  0) 返回上级菜单"
        echo ""
        echo "--------------------------------------------"

        echo -n "请输入选项编号 [0-8]: "
        read -r choice

        if [ -z "$choice" ]; then
            echo ""
            continue
        fi

        case "$choice" in
            1|2|3|4|5)
                local provider_list=("adoptium" "liberica" "corretto" "zulu" "openjdk")
                local selected_provider="${provider_list[$((choice - 1))]}"
                cli_show_provider_info "$selected_provider"
                ;;
            6)
                cli_set_default_provider
                ;;
            7)
                cli_toggle_provider
                ;;
            8)
                cli_view_all_providers_detail
                ;;
            0)
                echo ""
                echo "返回上一级菜单..."
                echo ""
                break
                ;;
            *)
                echo ""
                echo -e "${RED}无效选项 '$choice'，请重新输入${NC}"
                echo ""
                ;;
        esac
    done
}

# 显示单个供应商信息
cli_show_provider_info() {
    local provider="$1"
    local enabled=$(jq -r ".providers.enabled.$provider // true" "$CONFIG_FILE")

    clear 2>/dev/null || printf "\033[2J\033[H"
    echo ""
    echo "============================================"
    echo "    ${JDK_PROVIDERS[$provider]}"
    echo "============================================"
    echo ""
    echo -e "  ${CYAN}状态:${NC} $([ "$enabled" = "true" ] && echo -e "${GREEN}启用${NC}" || echo -e "${RED}禁用${NC}")"
    echo -e "  ${CYAN}支持版本:${NC} ${PROVIDER_VERSIONS[$provider]}"
    echo -e "  ${CYAN}特性:${NC} ${PROVIDER_FEATURES[$provider]}"
    echo -e "  ${CYAN}描述:${NC} ${PROVIDER_DESCRIPTIONS[$provider]}"
    echo -e "  ${CYAN}官网:${NC} ${PROVIDER_URLS[$provider]}"
    echo ""

    if [ "$provider" = "$DEFAULT_PROVIDER" ]; then
        echo -e "  ${YELLOW}※ 当前设置为默认供应商${NC}"
        echo ""
    fi

    echo "--------------------------------------------"
    echo -n "按回车键返回..."
    read -r
}

# 设置默认供应商
cli_set_default_provider() {
    echo ""
    echo "============================================"
    echo "        设置默认供应商"
    echo "============================================"
    echo ""

    local index=1
    local provider_list=()
    for provider in adoptium liberica corretto zulu openjdk; do
        local enabled=$(jq -r ".providers.enabled.$provider // true" "$CONFIG_FILE")
        if [ "$enabled" = "true" ]; then
            echo "  $index) ${JDK_PROVIDERS[$provider]}"
            provider_list+=("$provider")
            index=$((index + 1))
        fi
    done

    echo ""
    echo -n "请选择默认供应商编号: "
    read -r choice

    if [ -z "$choice" ]; then
        return
    fi

    local selected_index=$((choice - 1))
    if [ "$selected_index" -ge 0 ] && [ "$selected_index" -lt "${#provider_list[@]}" ]; then
        local new_default="${provider_list[$selected_index]}"
        jq --arg provider "$new_default" '.providers.default = $provider' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
        DEFAULT_PROVIDER="$new_default"
        echo ""
        echo -e "${GREEN}默认供应商已设置为: ${JDK_PROVIDERS[$new_default]}${NC}"
    else
        echo ""
        echo -e "${RED}无效选择${NC}"
    fi

    echo ""
    echo -n "按回车键返回..."
    read -r
}

# 启用/禁用供应商
cli_toggle_provider() {
    echo ""
    echo "============================================"
    echo "        启用/禁用供应商"
    echo "============================================"
    echo ""

    local index=1
    for provider in adoptium liberica corretto zulu openjdk; do
        local enabled=$(jq -r ".providers.enabled.$provider // true" "$CONFIG_FILE")
        local status="[${GREEN}启用${NC}]"
        if [ "$enabled" = "false" ]; then
            status="[${RED}禁用${NC}]"
        fi
        echo "  $index) ${JDK_PROVIDERS[$provider]} $status"
        index=$((index + 1))
    done

    echo ""
    echo -n "请选择要切换状态的供应商编号: "
    read -r choice

    if [ -z "$choice" ]; then
        return
    fi

    local provider_list=("adoptium" "liberica" "corretto" "zulu" "openjdk")
    local selected_index=$((choice - 1))

    if [ "$selected_index" -ge 0 ] && [ "$selected_index" -lt 5 ]; then
        local selected_provider="${provider_list[$selected_index]}"
        local current_status=$(jq -r ".providers.enabled.$selected_provider // true" "$CONFIG_FILE")

        if [ "$current_status" = "true" ]; then
            jq --argjson enabled false --arg provider "$selected_provider" '.providers.enabled[$provider] = $enabled' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
            echo ""
            echo -e "${YELLOW}${JDK_PROVIDERS[$selected_provider]} 已禁用${NC}"
        else
            jq --argjson enabled true --arg provider "$selected_provider" '.providers.enabled[$provider] = $enabled' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
            echo ""
            echo -e "${GREEN}${JDK_PROVIDERS[$selected_provider]} 已启用${NC}"
        fi
    else
        echo ""
        echo -e "${RED}无效选择${NC}"
    fi

    echo ""
    echo -n "按回车键返回..."
    read -r
}

# 查看所有供应商详情
cli_view_all_providers_detail() {
    clear 2>/dev/null || printf "\033[2J\033[H"

    echo ""
    echo "============================================"
    echo "      JDK 供应商详细信息"
    echo "============================================"
    echo ""

    for provider in adoptium liberica corretto zulu openjdk; do
        local enabled=$(jq -r ".providers.enabled.$provider // true" "$CONFIG_FILE")
        local default_mark=""
        if [ "$provider" = "$DEFAULT_PROVIDER" ]; then
            default_mark=" ${YELLOW}[默认]${NC}"
        fi

        echo -e "  ${CYAN}${JDK_PROVIDERS[$provider]}${default_mark}${NC}"
        echo -e "    状态: $([ "$enabled" = "true" ] && echo -e "${GREEN}启用${NC}" || echo -e "${RED}禁用${NC}")"
        echo -e "    版本: ${PROVIDER_VERSIONS[$provider]}"
        echo -e "    特性: ${PROVIDER_FEATURES[$provider]}"
        echo -e "    描述: ${PROVIDER_DESCRIPTIONS[$provider]}"
        echo ""
    done

    echo "--------------------------------------------"
    echo -n "按回车键返回..."
    read -r
}

# ============================================
# GUI JDK 供应商管理
# ============================================

manage_jdk_providers() {
    while true; do
        # 获取当前默认供应商
        local current_default=$(jq -r '.providers.default // "adoptium"' "$CONFIG_FILE")

        choice=$(safe_whiptail --nocancel --clear \
            --title "JDK 供应商管理" \
            --menu "当前默认: ${JDK_PROVIDERS[$current_default]}\n请选择操作：" 18 60 6 \
            "1" "查看所有供应商" \
            "2" "设置默认供应商" \
            "3" "启用/禁用供应商" \
            "4" "查看供应商详情" \
            "0" "返回上级菜单" \
            3>&1 1>&2 2>&3)

        case $choice in
            1) show_all_providers ;;
            2) gui_set_default_provider ;;
            3) gui_toggle_provider ;;
            4) gui_show_provider_detail ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# GUI 显示所有供应商
show_all_providers() {
    local provider_list=""
    local current_default=$(jq -r '.providers.default // "adoptium"' "$CONFIG_FILE")

    for provider in adoptium liberica corretto zulu openjdk; do
        local enabled=$(jq -r ".providers.enabled.$provider // true" "$CONFIG_FILE")
        local status="启用"
        local check="[X]"

        if [ "$enabled" = "false" ]; then
            status="禁用"
            check="[ ]"
        fi

        local default_mark=""
        if [ "$provider" = "$current_default" ]; then
            default_mark=" (默认)"
        fi

        provider_list="$provider_list${JDK_PROVIDERS[$provider]}$default_mark $check $status\n"
    done

    safe_whiptail --msgbox --title "JDK 供应商列表" "$provider_list" 15 60
}

# GUI 设置默认供应商
gui_set_default_provider() {
    local options=()
    local provider_array=()

    for provider in adoptium liberica corretto zulu openjdk; do
        local enabled=$(jq -r ".providers.enabled.$provider // true" "$CONFIG_FILE")
        if [ "$enabled" = "true" ]; then
            options+=("$provider" "${JDK_PROVIDERS[$provider]}")
            provider_array+=("$provider")
        fi
    done

    local selected=$(safe_whiptail --title "设置默认供应商" --menu "选择默认供应商：" 15 50 5 "${options[@]}" 3>&1 1>&2 2>&3)

    if [ -n "$selected" ]; then
        jq --arg provider "$selected" '.providers.default = $provider' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
        DEFAULT_PROVIDER="$selected"
        show_msg "成功" "默认供应商已设置为: ${JDK_PROVIDERS[$selected]}"
    fi
}

# GUI 启用/禁用供应商
gui_toggle_provider() {
    local current_default=$(jq -r '.providers.default // "adoptium"' "$CONFIG_FILE")

    # 先显示所有供应商状态
    local options=()
    for provider in adoptium liberica corretto zulu openjdk; do
        local enabled=$(jq -r ".providers.enabled.$provider // true" "$CONFIG_FILE")
        local status="启用"
        if [ "$enabled" = "false" ]; then
            status="禁用"
        fi

        # 如果是默认供应商，提示无法禁用
        if [ "$provider" = "$current_default" ]; then
            options+=("$provider" "${JDK_PROVIDERS[$provider]} [$status] [默认]")
        else
            options+=("$provider" "${JDK_PROVIDERS[$provider]} [$status]")
        fi
    done

    local selected=$(safe_whiptail --title "选择供应商" --menu "选择要切换状态的供应商：" 15 55 5 "${options[@]}" 3>&1 1>&2 2>&3)

    if [ -n "$selected" ]; then
        if [ "$selected" = "$current_default" ]; then
            show_msg "提示" "无法禁用默认供应商，请先设置其他供应商为默认"
            return
        fi

        local current_status=$(jq -r ".providers.enabled.$selected // true" "$CONFIG_FILE")
        local new_status="false"
        local status_text="禁用"

        if [ "$current_status" = "false" ]; then
            new_status="true"
            status_text="启用"
        fi

        jq --argjson enabled "$new_status" --arg provider "$selected" '.providers.enabled[$provider] = $enabled' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
        show_msg "成功" "${JDK_PROVIDERS[$selected]} 已$status_text"
    fi
}

# GUI 查看供应商详情
gui_show_provider_detail() {
    local options=()
    for provider in adoptium liberica corretto zulu openjdk; do
        options+=("$provider" "${JDK_PROVIDERS[$provider]}")
    done

    local selected=$(safe_whiptail --title "选择供应商" --menu "选择要查看详情的供应商：" 15 50 5 "${options[@]}" 3>&1 1>&2 2>&3)

    if [ -n "$selected" ]; then
        local enabled=$(jq -r ".providers.enabled.$selected // true" "$CONFIG_FILE")
        local status="启用"
        if [ "$enabled" = "false" ]; then
            status="禁用"
        fi

        local default_mark=""
        local current_default=$(jq -r '.providers.default // "adoptium"' "$CONFIG_FILE")
        if [ "$selected" = "$current_default" ]; then
            default_mark="\n* 当前为默认供应商"
        fi

        local msg="状态: $status\n"
        msg+="支持版本: ${PROVIDER_VERSIONS[$selected]}\n"
        msg+="特性: ${PROVIDER_FEATURES[$selected]}\n\n"
        msg+="描述: ${PROVIDER_DESCRIPTIONS[$selected]}\n"
        msg+="官网: ${PROVIDER_URLS[$selected]}$default_mark"

        safe_whiptail --msgbox --title "${JDK_PROVIDERS[$selected]}" "$msg" 15 55
    fi
}

# CLI 安装 JDK
cli_install_jdk() {
    local jdk_version provider

    jdk_version=$(ui_input "请输入要安装的 JDK 版本（如 17, 21）")
    if [ -z "$jdk_version" ]; then
        echo "错误: JDK 版本不能为空"
        return 1
    fi

    # 检查是否已安装
    if jdk_exists "$jdk_version"; then
        echo "JDK $jdk_version 已安装"
        return
    fi

    # 选择供应商
    echo ""
    echo "=== 选择 JDK 供应商 ==="
    echo ""

    local index=1
    local provider_options=()
    local enabled_count=0

    for provider_id in adoptium liberica corretto zulu openjdk; do
        local enabled=$(jq -r ".providers.enabled.$provider_id // true" "$CONFIG_FILE" 2>/dev/null)
        local default_mark=""

        if [ "$provider_id" = "$DEFAULT_PROVIDER" ]; then
            default_mark=" [默认]"
        fi

        if [ "$enabled" = "true" ]; then
            local features="${PROVIDER_FEATURES[$provider_id]:-}"
            echo -e "  ${GREEN}$index)${NC} ${JDK_PROVIDERS[$provider_id]}${default_mark}"
            echo "      特性: $features"
            provider_options+=("$provider_id")
            index=$((index + 1))
            enabled_count=$((enabled_count + 1))
        fi
    done

    if [ "$enabled_count" = "0" ]; then
        echo "错误: 没有启用的供应商，请先在供应商管理中启用"
        echo -n "按回车键返回... "
        read -r
        return 1
    fi

    echo ""
    echo -n "请选择供应商编号 [1-$enabled_count]: "
    read -r choice

    if [ -z "$choice" ]; then
        return
    fi

    local selected_index=$((choice - 1))
    if [ "$selected_index" -ge 0 ] && [ "$selected_index" -lt "$enabled_count" ]; then
        provider="${provider_options[$selected_index]}"
        echo ""
        echo -e "已选择: ${CYAN}${JDK_PROVIDERS[$provider]}${NC}"
    else
        echo ""
        echo -e "${RED}无效选择，使用默认供应商${NC}"
        provider="$DEFAULT_PROVIDER"
    fi

    echo "正在安装 JDK $jdk_version..."
    if install_jdk_version "$jdk_version" "$provider"; then
        echo "JDK $jdk_version 安装成功"
    else
        echo "JDK $jdk_version 安装失败"
        return 1
    fi
}

# CLI 管理已安装的 JDK
cli_manage_installed_jdks() {
    # 获取已安装的 JDK 列表
    local jdks=()

    if [ -d "$MCJDK_DIR" ]; then
        # 使用 for 循环代替 while read
        for jdk_dir in "$MCJDK_DIR"/*; do
            [ -d "$jdk_dir" ] || continue
            local jdk_name=$(basename "$jdk_dir")
            # 过滤掉非 JDK 目录
            [[ "$jdk_name" == jdk* ]] || continue
            jdks+=("$jdk_name:$jdk_name")
        done
    fi

    if [ ${#jdks[@]} -eq 0 ]; then
        echo ""
        echo -e "${YELLOW}没有已安装的 JDK${NC}"
        echo ""
        echo -n "按回车键返回... "
        read -r
        return 0
    fi

    # 选择 JDK
    local selected
    selected=$(ui_select "选择 JDK" "${jdks[@]}")
    [ $? -ne 0 ] || [ -z "$selected" ] && return

    # 提取 jdk 名称
    local jdk_name="${selected%%:*}"

    # JDK 管理菜单
    while true; do
        echo ""
        echo "=== JDK 管理: $jdk_name ==="
        echo ""
        echo "  1) 查看详细信息"
        echo "  2) 卸载 JDK"
        echo "  0) 返回"
        echo ""
        echo -n "请选择操作 [0-2]: "
        read -r choice

        case "$choice" in
            1)
                # 查看详细信息
                local jdk_info
                jdk_info=$(show_jdk_detailed_info "$jdk_name")
                echo ""
                echo "$jdk_info"
                echo ""
                ;;
            2)
                # 卸载 JDK
                if ui_confirm "确定要卸载 JDK $jdk_name 吗？此操作不可恢复！"; then
                    uninstall_jdk "$jdk_name"
                fi
                break
                ;;
            0)
                break
                ;;
            *)
                echo "无效选项，请重新输入"
                ;;
        esac
    done
}

# 安装JDK
install_jdk() {
    # 获取可用的JDK版本
    local available_versions=$(get_available_jdk_versions)
    if [ -z "$available_versions" ]; then
        ui_message "错误" "无法获取可用的JDK版本列表"
        return 1
    fi

    # 转换为选项数组（GUI 模式）
    local version_list=()
    # 确保按行分割版本
    while IFS= read -r version; do
        [ -z "$version" ] && continue
        version_list+=("$version" "JDK $version")
    done <<< "$(echo "$available_versions" | tr ' ' '\n')"

    # GUI 模式：使用 whiptail 选择JDK版本
    # 注意：高度设置为 24 以显示更多版本，避免内容超出窗口
    jdk_version=$(safe_whiptail --title "安装 JDK" --menu "选择JDK版本：" 15 40 5 "${version_list[@]}" 3>&1 1>&2 2>&3)
    if [ $? -ne 0 ] || [ -z "$jdk_version" ]; then
        return
    fi

    # 检查是否已安装
    if jdk_exists "$jdk_version"; then
        ui_message "信息" "JDK $jdk_version 已安装"
        return
    fi

    # GUI 模式：使用 whiptail 选择JDK提供商
    local providers_gui=()
    for provider_id in adoptium liberica corretto zulu openjdk; do
        local enabled=$(jq -r ".providers.enabled.$provider_id // true" "$CONFIG_FILE")
        if [ "$enabled" = "true" ]; then
            local features="${PROVIDER_FEATURES[$provider_id]}"
            providers_gui+=("$provider_id" "${JDK_PROVIDERS[$provider_id]} ($features)")
        fi
    done

    if [ ${#providers_gui[@]} -eq 0 ]; then
        ui_message "错误" "没有启用的供应商，请先在供应商管理中启用"
        return
    fi

    provider=$(safe_whiptail --title "选择供应商" --menu "选择JDK提供商：" 15 60 5 "${providers_gui[@]}" 3>&1 1>&2 2>&3)
    if [ $? -ne 0 ] || [ -z "$provider" ]; then
        return
    fi

    # 对于旧版本，检查提供商支持
    if [ "$jdk_version" -lt 8 ] && [ "$provider" != "openjdk" ]; then
        if ui_confirm "JDK $jdk_version 是较旧的版本，可能只有OpenJDK提供官方构建。是否继续使用 $provider？"; then
            :
        else
            provider="openjdk"
        fi
    fi

    # 下载并安装JDK
    if install_jdk_version "$jdk_version" "$provider"; then
        ui_message "成功" "JDK $jdk_version 安装成功"
    else
        ui_message "错误" "JDK $jdk_version 安装失败"
    fi
}

# 获取可用的 JDK 版本列表
get_available_jdk_versions() {
    # 尝试从多个来源获取版本列表
    local versions=""
    
    # 从 Adoptium API 获取
    versions=$(get_adoptium_versions)
    if [ -n "$versions" ]; then
        echo "$versions"
        return 0
    fi
    
    # 从 Liberica API 获取
    versions=$(get_liberica_versions)
    if [ -n "$versions" ]; then
        echo "$versions"
        return 0
    fi
    
    # 使用内置的常用版本列表
    echo "21 17 16 11 8 7 6"
}

# 从 Adoptium API 获取版本列表
get_adoptium_versions() {
    local api_url="https://api.adoptium.net/v3/info/available_releases"
    local response=$(curl -s --connect-timeout 10 "$api_url")
    
    if [ -z "$response" ] || [ "$response" = "null" ]; then
        return 1
    fi
    
    # 解析 JSON 获取版本列表
    local versions=$(echo "$response" | jq -r '.available_releases[]' 2>/dev/null)
    if [ $? -eq 0 ] && [ -n "$versions" ]; then
        # 包含旧版本（JDK 6, 7, 8）
        echo "$versions" | sort -nr
        return 0
    fi
    
    return 1
}

# 从 Liberica API 获取版本列表
get_liberica_versions() {
    local api_url="https://api.bell-sw.com/v1/liberica/releases?version-feature"
    local response=$(curl -s --connect-timeout 10 "$api_url")
    
    if [ -z "$response" ] || [ "$response" = "null" ]; then
        return 1
    fi
    
    # 解析 JSON 获取版本列表
    local versions=$(echo "$response" | jq -r '.[].version' 2>/dev/null | cut -d. -f1 | sort -nu | tail -10)
    if [ $? -eq 0 ] && [ -n "$versions" ]; then
        echo "$versions" | sort -nr
        return 0
    fi
    
    return 1
}

# 检查JDK是否存在
jdk_exists() {
    local jdk_version=$1
    local jdk_name="jdk$jdk_version"
    
    if [ -d "$MCJDK_DIR/$jdk_name" ] && [ -f "$MCJDK_DIR/$jdk_name/bin/java" ]; then
        return 0
    else
        return 1
    fi
}

# 安装指定版本的JDK
install_jdk_version() {
    local jdk_version=$1
    local selected_provider=$2
    local jdk_dir="$MCJDK_DIR/jdk$jdk_version"

    # 确保目标目录存在
    if [ ! -d "$MCJDK_DIR" ]; then
        mkdir -p "$MCJDK_DIR"
    fi

    # 获取下载链接
    echo -e "${BLUE}正在获取 JDK $jdk_version 下载链接...${NC}"
    local download_url=$(get_jdk_download_url "$jdk_version" "$selected_provider" "$ARCH")
    
    if [ -z "$download_url" ]; then
        echo -e "${RED}错误: 无法获取 JDK $jdk_version 的下载链接${NC}"
        return 1
    fi
    
    # 从下载URL中提取实际使用的provider
    local actual_provider="$selected_provider"
    if [[ "$download_url" == *"adoptium"* ]] || [[ "$download_url" == *"eclipse"* ]]; then
        actual_provider="adoptium"
    elif [[ "$download_url" == *"liberica"* ]] || [[ "$download_url" == *"bell-sw"* ]]; then
        actual_provider="liberica"
    elif [[ "$download_url" == *"corretto"* ]] || [[ "$download_url" == *"amazon"* ]]; then
        actual_provider="corretto"
    elif [[ "$download_url" == *"zulu"* ]] || [[ "$download_url" == *"azul"* ]]; then
        actual_provider="zulu"
    elif [[ "$download_url" == *"openjdk"* ]] || [[ "$download_url" == *"java.net"* ]]; then
        actual_provider="openjdk"
    fi
    
    # 如果实际使用的provider与选择的不同，显示提示
    if [ "$actual_provider" != "$selected_provider" ]; then
        echo -e "${YELLOW}注意: 使用备用提供商 $actual_provider 替代 $selected_provider${NC}"
    fi
    
    # 创建目录
    mkdir -p "$jdk_dir"
    
    echo -e "${GREEN}使用下载链接: $download_url${NC}"
    
    # 下载文件
    if download_with_progress "$download_url" "$jdk_dir/jdk.tar.gz" "正在下载" "JDK $jdk_version..."; then
        # 解压文件 (使用进度条)

        # 创建临时解压目录
        local temp_extract_dir="$jdk_dir/temp_extract"
        mkdir -p "$temp_extract_dir"

        # 先统计压缩包内的文件总数
        local total_files=$(tar -tzf "$jdk_dir/jdk.tar.gz" 2>/dev/null | wc -l)
        if [ -z "$total_files" ] || [ "$total_files" -eq 0 ]; then
            total_files=100  # 默认值
        fi

        # 后台解压到临时目录
        tar -xzf "$jdk_dir/jdk.tar.gz" -C "$temp_extract_dir" --strip-components=1 &
        local tar_pid=$!

        # 监控解压进度 (带箭头样式)
        local bar_width=$(get_progress_bar_width)
        local percent=0
        while kill -0 $tar_pid 2>/dev/null; do
            # 统计已解压的文件数量
            local extracted_files=$(find "$temp_extract_dir" -type f 2>/dev/null | wc -l)
            percent=$((extracted_files * 100 / total_files))
            if [ $percent -gt 100 ]; then
                percent=100
            fi
            if [ $percent -eq 0 ]; then
                percent=1  # 刚开始解压时显示1%
            fi

            # 使用和下载一样的进度条格式 (黄色)
            update_progress_bar_with_width "正在解压" "JDK..." "$percent" "$bar_width" ""
            sleep 0.2
        done

        wait $tar_pid
        local tar_status=$?

        # 检查是否还有 .tar 文件需要解压（某些下载源会双重打包）
        local inner_tar=$(find "$temp_extract_dir" -maxdepth 2 -name "*.tar" -type f 2>/dev/null | head -1)
        if [ -n "$inner_tar" ]; then
            echo -e "${YELLOW}检测到内部 .tar 文件，继续解压...${NC}"
            local inner_temp="$jdk_dir/inner_temp"
            mkdir -p "$inner_temp"

            # 解压内部 tar 文件
            tar -xf "$inner_tar" -C "$inner_temp" --strip-components=1

            # 移动内部内容到外层
            mv "$inner_temp"/* "$temp_extract_dir/" 2>/dev/null
            rmdir "$inner_temp" 2>/dev/null
            rm -f "$inner_tar"
        fi

        # 显示最终100%并换行
        update_progress_bar_with_width "正在解压" "JDK..." "100" "$bar_width" ""

        if [ $tar_status -eq 0 ]; then
            # 移动文件到目标目录
            mv "$temp_extract_dir"/* "$jdk_dir/" 2>/dev/null
            rmdir "$temp_extract_dir" 2>/dev/null
            echo -e "${GREEN}解压完成${NC}"
            
            # 清理临时文件
            rm -f "$jdk_dir/jdk.tar.gz"
            
            # 验证安装
            if validate_jdk_installation "$jdk_dir"; then
                echo -e "${GREEN}JDK 安装验证成功${NC}"
                
                # 记录安装信息
                record_jdk_installation "$jdk_version" "$actual_provider" "$download_url"
                
                # 添加到配置
                add_jdk_to_config "jdk$jdk_version" "$actual_provider"

                return 0
            else
                echo -e "${RED}JDK 安装验证失败${NC}"
                rm -rf "$jdk_dir"
                return 1
            fi
        else
            echo -e "${RED}JDK 解压失败${NC}"
            rm -rf "$jdk_dir"
            return 1
        fi
    else
        echo -e "${RED}JDK 下载失败${NC}"
        rm -rf "$jdk_dir"
        return 1
    fi
}

# 使用用户提供的 API 获取 JDK 下载链接
get_jdk_url_from_api() {
    local jdk_version=$1
    local provider=$2
    local arch=$3

    # API 域名
    local api_base="http://download.hycexit.xyz"

    # 架构映射
    local api_arch=""
    case $arch in
        "amd64") api_arch="amd64" ;;
        "arm64") api_arch="arm64" ;;
        *) api_arch="amd64" ;;
    esac

    # 映射供应商名称
    local api_provider=""
    case $provider in
        "corretto") api_provider="corretto" ;;
        "openjdk") api_provider="openjdk" ;;
        "adoptium"|"zulu"|"liberica")
            # 这些不支持，使用 corretto 作为默认
            api_provider="corretto"
            ;;
        *) api_provider="corretto" ;;
    esac

    # 调用 API
    local api_url="$api_base/api/v2/jdk/retrieve/$api_arch/$api_provider/$jdk_version"
    local response=$(curl -s --connect-timeout 10 "$api_url")

    # 检查响应
    if [ -z "$response" ]; then
        return 1
    fi

    # 检查是否有错误
    if echo "$response" | grep -q '"error"'; then
        return 1
    fi

    # 解析下载链接
    local download_url=$(echo "$response" | grep -o '"download_url"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"download_url"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')

    if [ -n "$download_url" ]; then
        echo "$api_base$download_url"
        return 0
    fi

    return 1
}

# 获取 JDK 下载链接
get_jdk_download_url() {
    local jdk_version=$1
    local provider=$2
    local arch=$3

    local download_url=""

    # 优先使用用户提供的 API
    download_url=$(get_jdk_url_from_api "$jdk_version" "$provider" "$arch")
    if [ -n "$download_url" ]; then
        echo "$download_url"
        return 0
    fi

    # API 获取失败，使用原来的方法
    case $provider in
        "adoptium")
            download_url=$(get_adoptium_url "$jdk_version" "$arch")
            ;;
        "liberica")
            download_url=$(get_liberica_url "$jdk_version" "$arch")
            ;;
        "corretto")
            download_url=$(get_corretto_url "$jdk_version" "$arch")
            ;;
        "zulu")
            download_url=$(get_zulu_url "$jdk_version" "$arch")
            ;;
        "openjdk")
            download_url=$(get_openjdk_url "$jdk_version" "$arch")
            ;;
        *)
            download_url=$(get_adoptium_url "$jdk_version" "$arch")
            ;;
    esac

    # 验证链接有效性
    if [ -n "$download_url" ] && validate_download_url "$download_url"; then
        echo "$download_url"
        return 0
    fi

    # 如果首选提供商失败，尝试备用方案
    echo -e "${YELLOW}警告: $provider 提供商获取失败，尝试备用方案...${NC}" >&2
    
    for backup_provider in "adoptium" "liberica" "zulu" "corretto" "openjdk"; do
        if [ "$backup_provider" != "$provider" ]; then
            download_url=$(get_jdk_url_by_provider "$jdk_version" "$arch" "$backup_provider")
            if [ -n "$download_url" ] && validate_download_url "$download_url"; then
                echo -e "${YELLOW}使用备用提供商: $backup_provider${NC}" >&2
                echo "$download_url"
                return 0
            fi
        fi
    done
    
    # 所有API都失败，使用备用链接
    echo -e "${RED}错误: 所有API都失败，使用备用链接${NC}" >&2
    get_adoptium_url_fallback "$jdk_version" "$arch"
}

# 按提供商获取下载链接
get_jdk_url_by_provider() {
    local jdk_version=$1
    local arch=$2
    local provider=$3
    
    case $provider in
        "adoptium") get_adoptium_url "$jdk_version" "$arch" ;;
        "liberica") get_liberica_url "$jdk_version" "$arch" ;;
        "corretto") get_corretto_url "$jdk_version" "$arch" ;;
        "zulu") get_zulu_url "$jdk_version" "$arch" ;;
        *) get_adoptium_url "$jdk_version" "$arch" ;;
    esac
}

# Adoptium (Eclipse Temurin) API
get_adoptium_url() {
    local jdk_version=$1
    local arch=$2

    # 如果 jq 不可用，使用备用链接
    if ! command -v jq &> /dev/null; then
        get_adoptium_url_fallback "$jdk_version" "$arch"
        return $?
    fi

    # 架构映射
    case $arch in
        "amd64") api_arch="x64" ;;
        "arm64") api_arch="aarch64" ;;
        *) api_arch="x64" ;;
    esac

    # 使用 Adoptium API v3
    local api_url="https://api.adoptium.net/v3/assets/latest/$jdk_version/hotspot"
    local response=$(curl -s --connect-timeout 10 "$api_url")

    if [ -z "$response" ] || [ "$response" = "null" ]; then
        return 1
    fi

    # 解析 JSON 获取下载链接（过滤 linux + jdk 类型，排除 debugimage）
    local download_url=$(echo "$response" | jq -r ".[] | select(.binary.architecture == \"$api_arch\") | select(.binary.os == \"linux\") | select(.binary.image_type == \"jdk\") | .binary.package.link" 2>/dev/null)

    if [ -z "$download_url" ] || [ "$download_url" = "null" ]; then
        return 1
    fi

    echo "$download_url"
}

# Liberica JDK (使用备用链接，因为 API 不稳定)
get_liberica_url() {
    local jdk_version=$1
    local arch=$2

    # 架构映射
    case $arch in
        "amd64") api_arch="x64" ;;
        "arm64") api_arch="aarch64" ;;
        *) api_arch="x64" ;;
    esac

    # Liberica 备用下载链接
    case $jdk_version in
        21)
            echo "https://downloads.bell-sw.com/v21/21.0.5+11/bell-sw-jdk-${api_arch}-21.0.5+11-linux.tar.gz"
            ;;
        17)
            echo "https://downloads.bell-sw.com/v17/17.0.13+11/bell-sw-jdk-${api_arch}-17.0.13+11-linux.tar.gz"
            ;;
        11)
            echo "https://downloads.bell-sw.com/v11/11.0.25+10/bell-sw-jdk-${api_arch}-11.0.25+10-linux.tar.gz"
            ;;
        8)
            if [ "$arch" = "amd64" ]; then
                echo "https://downloads.bell-sw.com/v8/8.0.422+5/bell-sw-jdk-8.0.422+5-linux-x64.tar.gz"
            else
                echo "https://downloads.bell-sw.com/v8/8.0.422+5/bell-sw-jdk-8.0.422+5-linux-aarch64.tar.gz"
            fi
            ;;
        *)
            # 默认使用 adoptium 备用
            get_adoptium_url_fallback "$jdk_version" "$arch"
            ;;
    esac

    return 0
}

# Amazon Corretto API
get_corretto_url() {
    local jdk_version=$1
    local arch=$2
    
    # Corretto 使用固定的下载链接模式
    case $arch in
        "amd64")
            echo "https://corretto.aws/downloads/latest/amazon-corretto-$jdk_version-x64-linux-jdk.tar.gz"
            ;;
        "arm64")
            echo "https://corretto.aws/downloads/latest/amazon-corretto-$jdk_version-aarch64-linux-jdk.tar.gz"
            ;;
        *)
            echo "https://corretto.aws/downloads/latest/amazon-corretto-$jdk_version-x64-linux-jdk.tar.gz"
            ;;
    esac
}

# Zulu JDK API (Azul)
get_zulu_url() {
    local jdk_version=$1
    local arch=$2

    # 如果 jq 不可用，使用备用链接
    if ! command -v jq &> /dev/null; then
        get_adoptium_url_fallback "$jdk_version" "$arch"
        return $?
    fi

    # Zulu Community API
    local api_url="https://api.azul.com/zulu/download/community/v1.0/bundles/?os=linux&arch=$arch&javafx=false&jdk_version=$jdk_version"
    local response=$(curl -s --connect-timeout 10 "$api_url")

    if [ -z "$response" ] || [ "$response" = "null" ]; then
        return 1
    fi

    # 解析 JSON 获取下载链接 (zulu API 返回的是 .[].url，不是 download_url)
    local download_url=$(echo "$response" | jq -r '.[0].url' 2>/dev/null)

    if [ -z "$download_url" ] || [ "$download_url" = "null" ]; then
        return 1
    fi

    echo "$download_url"
}

# OpenJDK 直接下载链接 (由于 Oracle 改变了下载策略，现在使用 Adoptium 替代)
get_openjdk_url() {
    local jdk_version=$1
    local arch=$2

    # 架构映射
    case $arch in
        "amd64") api_arch="x64" ;;
        "arm64") api_arch="aarch64" ;;
        *) api_arch="x64" ;;
    esac

    # 使用 Adoptium 的 OpenJDK 构建（Eclipse Adoptium 就是 OpenJDK 的官方发行版）
    case $jdk_version in
        21)
            echo "https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.5%2B5/OpenJDK21U-jdk_${api_arch}_linux_hotspot_21.0.5_5.tar.gz"
            ;;
        17)
            echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.13%2B8/OpenJDK17U-jdk_${api_arch}_linux_hotspot_17.0.13_8.tar.gz"
            ;;
        11)
            echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.25%2B9/OpenJDK11U-jdk_${api_arch}_linux_hotspot_11.0.25_9.tar.gz"
            ;;
        8)
            if [ "$api_arch" = "x64" ]; then
                echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u432-b06/OpenJDK8U-jdk_x64_linux_hotspot_8u432b06.tar.gz"
            else
                echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u432-b06/OpenJDK8U-jdk_aarch64_linux_hotspot_8u432b06.tar.gz"
            fi
            ;;
        *)
            echo ""
            ;;
    esac
}

# 验证下载链接是否有效
validate_download_url() {
    local url=$1

    # 检查URL格式
    if [[ ! "$url" =~ ^https?:// ]]; then
        return 1
    fi

    # 对于 GitHub 链接，使用更宽松的验证（因为某些环境下 SSL 有问题）
    if [[ "$url" == *"github.com"* ]]; then
        # GitHub releases 链接格式一般是固定的，直接返回成功
        if [[ "$url" == *"/releases/download/"* ]] && [[ "$url" == *".tar.gz"* || "$url" == *".zip"* ]]; then
            return 0
        fi
    fi

    # 使用HEAD请求检查链接有效性（带超时和重定向）
    local status_code=$(curl -s -o /dev/null -w "%{http_code}" -L -I --connect-timeout 10 -m 10 "$url" 2>/dev/null)

    # 检查常见成功状态码
    if [[ "$status_code" == "200" ]] || [[ "$status_code" == "302" ]] || [[ "$status_code" == "307" ]] || [[ "$status_code" == "301" ]]; then
        return 0
    else
        # 对于 GitHub releases，302 重定向后可能返回 404 或其他错误
        # 所以如果状态码以 2 开头，也认为有效
        if [[ "$status_code" =~ ^2 ]]; then
            return 0
        fi
        return 1
    fi
}

# 备用下载链接（当所有API都失败时使用）
get_adoptium_url_fallback() {
    local jdk_version=$1
    local arch=$2
    
    # 基于版本和架构的备用链接
    case $jdk_version in
        21)
            if [ "$arch" = "amd64" ]; then
                echo "https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21%2B35/OpenJDK21U-jdk_x64_linux_hotspot_21_35.tar.gz"
            else
                echo "https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21%2B35/OpenJDK21U-jdk_aarch64_linux_hotspot_21_35.tar.gz"
            fi
            ;;
        17)
            if [ "$arch" = "amd64" ]; then
                echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.9%2B9/OpenJDK17U-jdk_x64_linux_hotspot_17.0.9_9.tar.gz"
            else
                echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.9%2B9/OpenJDK17U-jdk_aarch64_linux_hotspot_17.0.9_9.tar.gz"
            fi
            ;;
        16)
            if [ "$arch" = "amd64" ]; then
                echo "https://github.com/adoptium/temurin16-binaries/releases/download/jdk-16.0.2%2B7/OpenJDK16U-jdk_x64_linux_hotspot_16.0.2_7.tar.gz"
            else
                echo "https://github.com/adoptium/temurin16-binaries/releases/download/jdk-16.0.2%2B7/OpenJDK16U-jdk_aarch64_linux_hotspot_16.0.2_7.tar.gz"
            fi
            ;;
        11)
            if [ "$arch" = "amd64" ]; then
                echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.21%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.21_9.tar.gz"
            else
                echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.21%2B9/OpenJDK11U-jdk_aarch64_linux_hotspot_11.0.21_9.tar.gz"
            fi
            ;;
        8)
            if [ "$arch" = "amd64" ]; then
                echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u392-b08/OpenJDK8U-jdk_x64_linux_hotspot_8u392b08.tar.gz"
            else
                echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u392-b08/OpenJDK8U-jdk_aarch64_linux_hotspot_8u392b08.tar.gz"
            fi
            ;;
        7)
            if [ "$arch" = "amd64" ]; then
                echo "https://github.com/AdoptOpenJDK/openjdk7-binaries/releases/download/jdk7u80-b15/OpenJDK7U-jdk_x64_linux_hotspot_7u80b15.tar.gz"
            else
                # JDK 7 没有官方 ARM64 构建
                echo ""
            fi
            ;;
        6)
            if [ "$arch" = "amd64" ]; then
                echo "https://github.com/AdoptOpenJDK/openjdk6-binaries/releases/download/jdk6b38/OpenJDK6U-jdk_x64_linux_hotspot_6b38.tar.gz"
            else
                echo ""
            fi
            ;;
        *)
            # 对于不支持的版本，返回空
            echo ""
            return 1
            ;;
    esac
}

# 验证JDK安装
validate_jdk_installation() {
    local jdk_dir=$1

    # 检查必要的文件是否存在
    if [ ! -f "$jdk_dir/bin/java" ]; then
        echo -e "${RED}错误: 找不到 java 可执行文件${NC}"
        return 1
    fi

    # # 对于JDK 6和7，可能没有javac或者名称不同
    # if [ ! -f "$jdk_dir/bin/javac" ]; then
    #     echo -e "${YELLOW}警告: 找不到 javac 编译器${NC}"
    #     # 这不一定是错误，有些JDK发行版可能不包含开发工具
    # fi

    # 测试Java版本
    local java_cmd="$jdk_dir/bin/java"

    if ! "$java_cmd" -version >/dev/null 2>&1; then
        echo -e "${RED}错误: Java 可执行文件无法运行${NC}"
        return 1
    fi
    
    # 获取版本信息
    local version_info=$("$java_cmd" -version 2>&1 | head -1)
    echo -e "${GREEN}安装的Java版本: $version_info${NC}"
    
    return 0
}

# 记录JDK安装信息
record_jdk_installation() {
    local jdk_version=$1
    local provider=$2
    local download_url=$3
    local jdk_dir="$MCJDK_DIR/jdk$jdk_version"
    
    # 创建信息文件
    cat > "$jdk_dir/install.info" << EOF
# JDK 安装信息
版本: $jdk_version
提供商: $provider
下载链接: $download_url
安装时间: $(date)
安装路径: $jdk_dir
系统架构: $ARCH
用户选择: $selected_provider
实际使用: $actual_provider
EOF

    # 获取详细的版本信息
    local java_cmd="$jdk_dir/bin/java"
    if [ -f "$java_cmd" ]; then
        "$java_cmd" -version 2>&1 >> "$jdk_dir/install.info"
    fi
}

# 添加JDK到配置
add_jdk_to_config() {
    local name="$1"
    local provider="$2"
    local temp_file="$CONFIG_FILE.tmp"
    
    jq --arg name "$name" \
       --arg provider "$provider" \
       'if (.jdks | map(.name) | index($name)) then
            .jdks |= map(if .name == $name then .provider = $provider else . end)
        else
            .jdks += [{"name": $name, "provider": $provider}]
        end' \
       "$CONFIG_FILE" > "$temp_file" && mv "$temp_file" "$CONFIG_FILE"
}

# 管理已安装的JDK
manage_installed_jdks() {
    while true; do
        local jdks=()
        local jdk_info=()
        
        if [ -f "$CONFIG_FILE" ]; then
            while IFS= read -r jdk; do
                local name=$(echo "$jdk" | jq -r '.name')
                local provider=$(echo "$jdk" | jq -r '.provider')
                local jdk_version=${name#jdk}
                
                # 检查JDK目录是否存在
                if [ -d "$MCJDK_DIR/$name" ]; then
                    local java_path="$MCJDK_DIR/$name/bin/java"
                    local version_info=""
                    
                    if [ -f "$java_path" ]; then
                        version_info=$("$java_path" -version 2>&1 | head -1 | cut -d'"' -f2 2>/dev/null || echo "未知")
                    fi

                    jdks+=("$name" "$provider - $version_info")
                    jdk_info["$name"]="$provider|$version_info"
                else
                    # 如果目录不存在，从配置中移除
                    remove_jdk_from_config "$name"
                fi
            done < <(jq -c '.jdks[]' "$CONFIG_FILE")
        fi
        
        if [ ${#jdks[@]} -eq 0 ]; then
            show_msg "信息" "没有安装任何JDK"
            return
        fi
        
        # 添加安装新JDK选项
        jdks+=("install_new" "安装新JDK...")
        
        # 选择JDK
        selected=$(safe_whiptail --title "管理已安装的JDK" \
            --menu "选择要管理的JDK：" 15 50 6 "${jdks[@]}" 3>&1 1>&2 2>&3)
            
        if [ -z "$selected" ]; then
            return
        fi
        
        if [ "$selected" = "install_new" ]; then
            install_jdk
            return
        fi
        
        manage_installed_jdks_menu "$selected"
    done
}

manage_installed_jdks_menu() {
    local selected="$1"
    # JDK操作菜单
    while true; do
        local java_path="$MCJDK_DIR/$selected/bin/java"
        local version_info=""
        
        if [ -f "$java_path" ]; then
            version_info=$("$java_path" -version 2>&1 | head -1)
        fi
        
        choice=$(safe_whiptail --title "管理JDK: $selected" \
            --menu "JDK信息:\n$version_info\n\n请选择操作：" \
            18 50 8 \
            "1" "详细信息" \
            "2" "卸载JDK" \
            "0" "返回" \
            3>&1 1>&2 2>&3)

        case $choice in
            1) show_jdk_detailed_info "$selected" ;;
            2) uninstall_jdk "$selected" ; break ;;
            0) return ;;
            *) 
                show_msg "错误" "无效选项" 
                ;;
        esac
    done
}
 

# 查看JDK详细信息
show_jdk_detailed_info() {
    local jdk_name="$1"
    local jdk_dir="$MCJDK_DIR/$jdk_name"
    local jdk_version="${jdk_name#jdk}"

    # 获取Java版本信息
    local java_path="$jdk_dir/bin/java"
    if [ ! -f "$java_path" ]; then
        show_msg "错误" "Java可执行文件不存在: $java_path"
        return 1
    fi
    
    # 收集详细信息
    local info="JDK名称: $jdk_name\n"
    info+="版本号: $jdk_version\n"
    info+="安装路径: $jdk_dir\n"

    # Java版本信息
    local java_version=$("$java_path" -version 2>&1 | head -3)
    info+="----------------------------------------\n"
    info+="Java版本信息:\n$java_version\n"

    # 文件系统信息
    if [ -d "$jdk_dir" ]; then
        local dir_size=$(du -sh "$jdk_dir" 2>/dev/null | cut -f1 || echo "未知")
        local file_count=$(find "$jdk_dir" -type f 2>/dev/null | wc -l || echo "未知")
        # 兼容 Windows 和 Linux 的 stat 命令
        local install_time
        if stat --version &>/dev/null; then
            # Linux/Git Bash
            install_time=$(stat -c "%y" "$jdk_dir" 2>/dev/null | cut -d. -f1 || echo "未知")
        else
            # macOS/BSD 或其他
            install_time=$(stat -f "%Sm" "$jdk_dir" 2>/dev/null || echo "未知")
        fi

        info+="----------------------------------------\n"
        info+="安装大小: $dir_size\n"
        info+="文件数量: $file_count\n"
        info+="安装时间: $install_time\n"
    fi

    # 配置信息
    local config_info
    if [ -f "$CONFIG_FILE" ]; then
        config_info=$(jq -r --arg name "$jdk_name" '.jdks[] | select(.name == $name)' "$CONFIG_FILE" 2>/dev/null)
    fi
    if [ -n "$config_info" ] && [ "$config_info" != "null" ]; then
        local provider=$(echo "$config_info" | jq -r '.provider')
        info+="----------------------------------------\n"
        info+="提供商: $provider\n"
    fi

    # 检查使用此JDK的服务器
    local using_servers=()
    if [ -f "$CONFIG_FILE" ]; then
        while IFS= read -r server; do
            local server_name=$(echo "$server" | jq -r '.name')
            local server_jdk=$(echo "$server" | jq -r '.jdk_version // ""')
            if [ "$server_jdk" = "$jdk_version" ]; then
                using_servers+=("$server_name")
            fi
        done < <(jq -c '.servers[]' "$CONFIG_FILE" 2>/dev/null)
    fi

    if [ ${#using_servers[@]} -gt 0 ]; then
        info+="----------------------------------------\n"
        info+="使用此JDK的服务器:\n"
        for server in "${using_servers[@]}"; do
            info+="  • $server\n"
        done
    else
        info+="----------------------------------------\n"
        info+="使用此JDK的服务器: 无\n"
    fi

    # 使用更大的窗口显示
    if [ "$NO_GUI" = "true" ]; then
        echo ""
        echo "=== JDK详细信息: $jdk_name ==="
        echo ""
        echo -e "$info"
        echo ""
    else
        safe_whiptail --title "JDK详细信息: $jdk_name" --msgbox "$info" 25 65
    fi
}

# 显示JDK文件信息
show_jdk_file_info() {
    local jdk_name="$1"
    local filename="$2"
    local jdk_dir="$MCJDK_DIR/$jdk_name"
    local file_path="$jdk_dir/$filename"
    
    if [ ! -f "$file_path" ]; then
        show_msg "错误" "文件不存在: $filename"
        return
    fi
    
    # 收集文件信息
    local file_info="文件: $filename\n"
    file_info+="路径: $file_path\n"
    file_info+="大小: $(du -h "$file_path" | cut -f1)\n"
    file_info+="修改时间: $(stat -c "%y" "$file_path" | cut -d. -f1)\n"
    file_info+="权限: $(stat -c "%A" "$file_path")\n"
    
    # 文件类型
    local file_type=$(file -b "$file_path" 2>/dev/null || echo "未知")
    file_info+="类型: $file_type\n"
    
    # 如果是可执行文件，显示更多信息
    if [ -x "$file_path" ] && [[ "$filename" =~ ^(java|javac|jar)$ ]]; then
        file_info+="\n可执行文件信息:\n"
        "$file_path" -version 2>&1 | head -3 | while read -r line; do
            file_info+="$line\n"
        done
    fi
    
    # 显示文件信息
    ui_message "文件信息: $filename" "$file_info"
}

# 设置默认JDK

# 卸载JDK
uninstall_jdk() {
    local jdk_name="$1"
    local jdk_version="${jdk_name#jdk}"
    
    # 检查是否有服务器在使用此JDK
    local using_servers=()
    if [ -f "$CONFIG_FILE" ]; then
        while IFS= read -r server; do
            local server_name=$(echo "$server" | jq -r '.name')
            local server_jdk=$(echo "$server" | jq -r '.jdk_version // ""')
            if [ "$server_jdk" = "$jdk_version" ]; then
                using_servers+=("$server_name")
            fi
        done < <(jq -c '.servers[]' "$CONFIG_FILE")
    fi
    
    # 警告信息
    local warning_msg="确定要卸载 JDK $jdk_name 吗？\n\n"
    warning_msg+="这将删除JDK的所有文件。\n"
    
    if [ ${#using_servers[@]} -gt 0 ]; then
        warning_msg+="\n⚠️ 警告: 以下服务器正在使用此JDK:\n"
        for server in "${using_servers[@]}"; do
            warning_msg+="• $server\n"
        done
        warning_msg+="\n卸载后这些服务器将无法启动！"
    fi
    
    ui_confirm "$warning_msg"
    if [ $? -ne 0 ]; then
        return
    fi
    
    # 执行卸载
    local jdk_dir="$MCJDK_DIR/$jdk_name"
    
    if [ -d "$jdk_dir" ]; then
        # 删除目录
        if rm -rf "$jdk_dir"; then
            # 从配置中移除
            remove_jdk_from_config "$jdk_name"

            show_msg "成功" "JDK $jdk_name 已成功卸载"
        else
            show_msg "错误" "卸载失败，可能没有足够的权限"
        fi
    else
        # 目录不存在，只从配置中移除
        remove_jdk_from_config "$jdk_name"
        show_msg "成功" "已从配置中移除 JDK $jdk_name"
    fi
}

# 从配置中移除JDK
remove_jdk_from_config() {
    local jdk_name=$1
    local temp_file="$CONFIG_FILE.tmp"
    
    jq --arg name "$jdk_name" \
       'del(.jdks[] | select(.name == $name))' \
       "$CONFIG_FILE" > "$temp_file" && mv "$temp_file" "$CONFIG_FILE"
}

# JDK自动检测和修复系统
check_and_repair_jdk_environment() {
    echo -e "${BLUE}开始检查JDK环境...${NC}"

    local issues_found=0
    local fixed_issues=0

    # 检查配置中的所有JDK
    if [ -f "$CONFIG_FILE" ]; then
        while IFS= read -r jdk; do
            local name=$(echo "$jdk" | jq -r '.name')
            local provider=$(echo "$jdk" | jq -r '.provider')
            local jdk_version=${name#jdk}
            
            if ! jdk_exists "$jdk_version"; then
                echo -e "${YELLOW}警告: 配置中的JDK $name 不存在${NC}"
                ((issues_found++))
                
                if ui_confirm "配置中的JDK $name 不存在。是否尝试重新安装？"; then
                    if install_jdk_version "$jdk_version" "$provider"; then
                        echo -e "${GREEN}JDK $name 重新安装成功${NC}"
                        ((fixed_issues++))
                    else
                        echo -e "${RED}JDK $name 重新安装失败，从配置中移除${NC}"
                        remove_jdk_from_config "$name"
                    fi
                else
                    # 询问是否从配置中移除
                    if ui_confirm "是否从配置中移除无效的JDK $name？"; then
                        remove_jdk_from_config "$name"
                    fi
                fi
            fi
        done < <(jq -c '.jdks[]' "$CONFIG_FILE")
    fi
    
    # 检查服务器使用的JDK
    if [ -f "$CONFIG_FILE" ]; then
        while IFS= read -r server; do
            local server_name=$(echo "$server" | jq -r '.name')
            local server_jdk=$(echo "$server" | jq -r '.jdk_version // ""')
            
            if [ -n "$server_jdk" ] && ! jdk_exists "$server_jdk"; then
                echo -e "${YELLOW}警告: 服务器 $server_name 使用的JDK $server_jdk 不存在${NC}"
                ((issues_found++))
                
                # 获取服务器信息以确定需要的JDK版本
                local server_info=$(jq -r --arg name "$server_name" '.servers[] | select(.name == $name)' "$CONFIG_FILE")
                local mc_version=$(echo "$server_info" | jq -r '.version')
                local required_jdk=$(get_required_jdk_version "$mc_version")
                
                if ui_confirm "服务器 '$server_name' 使用的JDK $server_jdk 不存在。\n\nMinecraft版本: $mc_version\n需要JDK版本: $required_jdk\n\n是否自动安装并配置正确的JDK？"; then
                    if install_jdk_version "$required_jdk"; then
                        if configure_server_jdk "$server_name" "$required_jdk"; then
                            echo -e "${GREEN}服务器 $server_name 的JDK已修复${NC}"
                            ((fixed_issues++))
                        else
                            echo -e "${RED}服务器JDK配置失败${NC}"
                        fi
                    else
                        echo -e "${RED}JDK安装失败${NC}"
                    fi
                fi
            fi
        done < <(jq -c '.servers[]' "$CONFIG_FILE")
    fi
    
    # 总结报告
    if [ $issues_found -eq 0 ]; then
        echo -e "${GREEN}✓ JDK环境检查完成，未发现问题${NC}"
        ui_message "JDK环境检查" "JDK环境检查完成，未发现问题"
    else
        local summary="JDK环境检查完成:\n\n"
        summary+="发现问题: $issues_found\n"
        summary+="已修复: $fixed_issues\n"
        summary+="未修复: $((issues_found - fixed_issues))\n\n"
        
        if [ $fixed_issues -eq $issues_found ]; then
            summary+="✅ 所有问题已成功修复"
            echo -e "${GREEN}$summary${NC}"
        else
            summary+="⚠️ 部分问题需要手动处理"
            echo -e "${YELLOW}$summary${NC}"
        fi
        
        ui_message "JDK 检查结果" "$summary"
    fi
}

# 自动配置JDK
auto_configure_jdk() {
    while true; do
        local servers=()
        if [ -f "$CONFIG_FILE" ]; then
            while IFS= read -r server; do
                local name=$(echo "$server" | jq -r '.name')
                local type=$(echo "$server" | jq -r '.type')
                local version=$(echo "$server" | jq -r '.version')
                servers+=("$name:$type ($version)")
            done < <(jq -c '.servers[]' "$CONFIG_FILE")
        fi

        if [ ${#servers[@]} -eq 0 ]; then
            ui_message "信息" "没有可用的服务器"
            return
        fi

        echo ""
        echo "=== 自动配置 JDK ==="
        echo ""

        selected=$(ui_select "选择要配置JDK的服务器" "${servers[@]}")
        if [ -z "$selected" ]; then
            return
        fi

        # 获取服务器信息
        local server_info=$(jq -r --arg name "$selected" '.servers[] | select(.name == $name)' "$CONFIG_FILE")
        local server_type=$(echo "$server_info" | jq -r '.type')
        local mc_version=$(echo "$server_info" | jq -r '.version')

        # 确定所需的JDK版本
        local required_jdk=$(get_required_jdk_version "$mc_version")
        local recommended_jdk=$(get_recommended_jdk_version "$mc_version" "$server_type")

        # 显示JDK建议
        echo ""
        echo "服务器: $selected"
        echo "Minecraft版本: $mc_version"
        echo "服务器类型: $server_type"
        echo "必需JDK版本: $required_jdk"
        echo "推荐JDK版本: $recommended_jdk"
        echo ""

        if [ "$required_jdk" != "$recommended_jdk" ]; then
            echo -e "${YELLOW}注意: 推荐使用JDK $recommended_jdk 以获得最佳性能${NC}"
        fi
        echo ""

        # 选择要使用的JDK版本
        local jdk_choice=$(ui_select "选择JDK版本" "$required_jdk:必需版本" "$recommended_jdk:推荐版本" "custom:自定义版本")

        local final_jdk_version="$required_jdk"

        case "$jdk_choice" in
            "custom")
                local custom_jdk=$(ui_input "请输入自定义JDK版本" "$recommended_jdk")
                if [ -n "$custom_jdk" ] && validate_jdk_version "$custom_jdk"; then
                    final_jdk_version="$custom_jdk"
                else
                    ui_message "错误" "无效的JDK版本"
                    return
                fi
                ;;
            "$recommended_jdk")
                final_jdk_version="$recommended_jdk"
                ;;
            *)
                final_jdk_version="$required_jdk"
                ;;
        esac
        
        # 检查是否已安装所需JDK
        if ! jdk_exists "$final_jdk_version"; then
            # 询问是否安装
            if ui_confirm "需要JDK $final_jdk_version，但未安装。是否立即安装？"; then
                # 自动选择最佳提供商
                local best_provider=$(get_best_jdk_provider_for_version "$final_jdk_version")
                if ! install_jdk_version "$final_jdk_version" "$best_provider"; then
                    show_msg "错误" "JDK安装失败"
                    return
                fi
            else
                show_msg "信息" "取消操作"
                return
            fi
        fi
        
        # 配置服务器使用该JDK
        if configure_server_jdk "$selected" "$final_jdk_version"; then
            show_msg "成功" "已为服务器 '$selected' 配置JDK $final_jdk_version"
            
            # 显示配置信息
            local config_info="JDK配置完成！\n\n"
            config_info+="服务器: $selected\n"
            config_info+="Minecraft版本: $mc_version\n"
            config_info+="JDK版本: $final_jdk_version\n"
            config_info+="Java路径: $MCJDK_DIR/jdk$final_jdk_version/bin/java\n\n"
            config_info+="下次启动服务器时将使用配置的JDK版本。"
            
            ui_message "配置完成" "$config_info"
        else
            show_msg "错误" "JDK配置失败"
        fi
    done
}

# 获取推荐JDK版本（考虑服务器类型）
get_recommended_jdk_version() {
    local mc_version=$1
    local server_type=$2
    
    local required_jdk=$(get_required_jdk_version "$mc_version")
    
    # 根据服务器类型调整推荐版本
    case "$server_type" in
        "forge")
            # Forge通常需要更新的JDK版本
            case "$required_jdk" in
                8) echo "11" ;;
                11) echo "17" ;;
                17) echo "21" ;;
                *) echo "$required_jdk" ;;
            esac
            ;;
        "fabric")
            # Fabric对新版JDK支持较好
            case "$required_jdk" in
                8|11) echo "17" ;;
                17) echo "21" ;;
                *) echo "$required_jdk" ;;
            esac
            ;;
        "spigot"|"paper")
            # 插件服务器可以使用较新的JDK
            case "$required_jdk" in
                8) echo "11" ;;
                *) echo "$required_jdk" ;;
            esac
            ;;
        "folia")
            # Folia需要较新的JDK版本以获得最佳多线程性能
            case "$required_jdk" in
                8|11) echo "17" ;;
                17) echo "21" ;;
                *) echo "$required_jdk" ;;
            esac
            ;;
        *)
            echo "$required_jdk"
            ;;
    esac
}

# 获取所需的JDK版本
get_required_jdk_version() {
    local mc_version=$1
    
    # 安全地提取主版本号
    local major_version=$(echo "$mc_version" | awk -F. '{print $1}')
    local minor_version=$(echo "$mc_version" | awk -F. '{print $2}')
    
    if ! [[ "$major_version" =~ ^[0-9]+$ ]]; then
        echo "8" 
        return
    fi
    
    # Minecraft官方JDK版本要求
    # 来源: https://help.minecraft.net/hc/en-us/articles/360035131551
    case "$major_version" in
        1)
            case "$minor_version" in
                20|21) echo "21" ;;  # 1.20+ 需要Java 21
                17|18|19) echo "17" ;; # 1.17-1.19 需要Java 17
                16) echo "16" ;;       # 1.16 需要Java 16
                12|13|14|15) echo "11" ;; # 1.12-1.15 需要Java 11
                8|9|10|11) echo "8" ;; # 1.8-1.11 需要Java 8
                6|7) echo "7" ;;       # 1.6-1.7 需要Java 7
                *) echo "8" ;;         # 默认使用Java 8
            esac
            ;;
        21|22|23|24|25|26|27|28|29|30)
            echo "21" ;;  # 未来版本使用Java 21
        17|18|19|20)
            echo "17" ;;  # 中间版本使用Java 17
        11|12|13|14|15|16)
            echo "11" ;;  # 较新版本使用Java 11
        8|9|10)
            echo "8" ;;   # 基础版本使用Java 8
        *)
            # 根据版本号自动判断
            if [ "$major_version" -ge 21 ]; then
                echo "21"
            elif [ "$major_version" -ge 17 ]; then
                echo "17"
            elif [ "$major_version" -ge 11 ]; then
                echo "11"
            else
                echo "8"
            fi
            ;;
    esac
}

get_best_jdk_provider_for_version() {
    local jdk_version=$1
    
    # 根据版本选择最佳提供商
    case $jdk_version in
        6|7|8)
            # 旧版本使用Adoptium或Liberica
            echo "adoptium"
            ;;
        11|16)
            # 中间版本多提供商支持
            echo "liberica"
            ;;
        17|21)
            # 新版本使用最新提供商
            echo "adoptium"
            ;;
        *)
            # 默认选择
            echo "adoptium"
            ;;
    esac
}

# 配置服务器使用指定JDK
configure_server_jdk() {
    local server_name="$1"
    local jdk_version="$2"
    local server_dir="$MCSERVER_DIR/$server_name"
    local jdk_dir="$MCJDK_DIR/jdk$jdk_version"
    
    # 验证JDK目录
    if [ ! -d "$jdk_dir" ]; then
        echo -e "${RED}错误: JDK目录不存在: $jdk_dir${NC}"
        return 1
    fi
    
    # 验证Java可执行文件
    local java_path="$jdk_dir/bin/java"
    if [ ! -f "$java_path" ] && [ ! -x "$java_path" ]; then
        echo -e "${RED}错误: Java可执行文件不存在或不可执行: $java_path${NC}"
        return 1
    fi
    
    # 获取服务器信息
    local server_info=$(jq -r --arg name "$server_name" '.servers[] | select(.name == $name)' "$CONFIG_FILE")
    local server_type=$(echo "$server_info" | jq -r '.type')
    local mc_version=$(echo "$server_info" | jq -r '.version')
    
    # 验证版本兼容性
    if ! validate_mc_jdk_compatibility "$mc_version" "$jdk_version"; then
        echo -e "${YELLOW}警告: Minecraft $mc_version 与 JDK $jdk_version 可能存在兼容性问题${NC}"
        ui_confirm "Minecraft $mc_version 与 JDK $jdk_version 可能存在兼容性问题。是否继续？"
        if [ $? -ne 0 ]; then
            return 1
        fi
    fi
    
    # 备份原启动脚本
    if [ -f "$server_dir/start.sh" ]; then
        local backup_time=$(date +%Y%m%d_%H%M%S)
        cp "$server_dir/start.sh" "$server_dir/start.sh.backup.$backup_time"
        echo -e "${GREEN}原启动脚本已备份: start.sh.backup.$backup_time${NC}"
    fi
    
    # 重新生成启动脚本
    echo -e "${BLUE}正在生成新的启动脚本...${NC}"
    if create_start_script "$server_dir" "$server_type" "$mc_version" "$jdk_version"; then
        echo -e "${GREEN}启动脚本已更新为使用 JDK $jdk_version${NC}"
        
        # 测试Java版本
        local java_version_output=$("$java_path" -version 2>&1 | head -3)
        echo -e "${BLUE}Java版本信息:${NC}"
        echo "$java_version_output"
        
        # 更新服务器配置
        update_server_jdk_config "$server_name" "$jdk_version"
        
        return 0
    else
        echo -e "${RED}启动脚本生成失败${NC}"
        # 恢复备份
        if [ -f "$server_dir/start.sh.backup.$backup_time" ]; then
            mv "$server_dir/start.sh.backup.$backup_time" "$server_dir/start.sh"
            echo -e "${YELLOW}已恢复原启动脚本${NC}"
        fi
        return 1
    fi
}

# 更新服务器JDK配置
update_server_jdk_config() {
    local server_name="$1"
    local jdk_version="$2"
    local temp_file="$CONFIG_FILE.tmp"
    
    jq --arg name "$server_name" \
       --arg jdk_version "$jdk_version" \
       '(.servers[] | select(.name == $name)).jdk_version = $jdk_version' \
       "$CONFIG_FILE" > "$temp_file" && mv "$temp_file" "$CONFIG_FILE"
}

# 验证Minecraft和JDK兼容性
validate_mc_jdk_compatibility() {
    local mc_version=$1
    local jdk_version=$2
    
    local mc_major=$(echo "$mc_version" | awk -F. '{print $1}')
    local mc_minor=$(echo "$mc_version" | awk -F. '{print $2}')
    
    # 兼容性检查规则
    if [ "$mc_major" -eq 1 ]; then
        case "$mc_minor" in
            [0-7]) # 1.0-1.7
                if [ "$jdk_version" -gt 8 ]; then
                    echo -e "${YELLOW}警告: 旧版本Minecraft可能不兼容新版JDK${NC}"
                    return 1
                fi
                ;;
            [8-11]) # 1.8-1.11
                if [ "$jdk_version" -gt 11 ]; then
                    echo -e "${YELLOW}警告: 建议使用Java 8-11以获得最佳兼容性${NC}"
                    return 1
                fi
                ;;
        esac
    fi
    
    return 0
}

# 更新JDK列表
update_jdk_list() {
    echo -e "${BLUE}正在更新可用的JDK版本列表...${NC}"
    
    # 获取最新版本列表
    local new_versions=$(get_available_jdk_versions)
    
    if [ -z "$new_versions" ]; then
        show_msg "错误" "无法获取JDK版本列表"
        return 1
    fi
    
    # 显示可用的版本
    local message="可用的JDK版本:\n\n"
    while IFS= read -r version; do
        message+="• JDK $version\n"
    done <<< "$new_versions"
    
    ui_message "JDK版本列表" "$message"
    show_msg "成功" "JDK版本列表已更新"
}

# 内网穿透管理功能

# HPPRO 内网穿透管理菜单
hp_management() {
    # CLI 模式调用 CLI 版本
    if [ "$NO_GUI" = "true" ]; then
        cli_hp_management
        return
    fi

    while true; do
        # 获取内网穿透状态
        local hp_status
        if [ -f "$HP_DIR/hp-client" ]; then
            # 客户端已下载
            if is_hp_running; then
                # 正在运行
                hp_status="运行中"
                if [ -f "$HP_DIR/hp-client.pid" ]; then
                    local pid=$(cat "$HP_DIR/hp-client.pid")
                    hp_status+=" (PID: $pid)"
                fi
            else
                # 已下载但未运行
                hp_status="未运行"
            fi
        else
            # 未下载客户端
            hp_status="未下载"
        fi

        # 获取日志文件信息
        local log_info="无日志文件"
        if [ -f "$HP_LOG_FILE" ]; then
            local log_size=$(du -h "$HP_LOG_FILE" | cut -f1)
            local log_lines=$(wc -l < "$HP_LOG_FILE" 2>/dev/null || echo "未知")
            log_info="${log_lines}行, ${log_size}"
        fi
        
        choice=$(safe_whiptail --nocancel --clear \
            --title "HPPRO 内网穿透管理" \
            --menu "当前状态: $hp_status\n设备ID: ${HP_DEVICE_ID:-未设置}\n日志文件: $log_info" 20 60 8 \
            "1" "启动穿透" \
            "2" "停止穿透" \
            "3" "设置设备ID" \
            "4" "穿透日志管理" \
            "5" "下载/更新客户端" \
            "6" "删除客户端" \
            "7" "打开内网穿透官网" \
            "0" "返回主菜单" \
            3>&1 1>&2 2>&3)

        case $choice in
            1) start_hp_service ;;
            2) stop_hp_service ;;
            3) set_device_id ;;
            4) hp_log_menu ;;
            5) download_hp_client ;;
            6) delete_hp_client ;;
            7) open_hp_website ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# ============================================
# CLI 内网穿透管理菜单
# ============================================

cli_hp_management() {
    while true; do
        # 清屏
        clear 2>/dev/null || printf "\033[2J\033[H"

        # 获取内网穿透状态
        local hp_status
        if [ -f "$HP_DIR/hp-client" ]; then
            if is_hp_running; then
                hp_status="运行中"
                if [ -f "$HP_DIR/hp-client.pid" ]; then
                    local pid=$(cat "$HP_DIR/hp-client.pid")
                    hp_status+=" (PID: $pid)"
                fi
            else
                hp_status="未运行"
            fi
        else
            hp_status="未下载"
        fi

        # 获取日志文件信息
        local log_info="无日志文件"
        if [ -f "$HP_LOG_FILE" ]; then
            local log_size=$(du -h "$HP_LOG_FILE" | cut -f1)
            local log_lines=$(wc -l < "$HP_LOG_FILE" 2>/dev/null || echo "未知")
            log_info="${log_lines}行, ${log_size}"
        fi

        echo ""
        echo "=== HPPRO 内网穿透管理 ==="
        echo ""
        echo "当前状态: $hp_status"
        echo "设备ID: ${HP_DEVICE_ID:-未设置}"
        echo "日志文件: $log_info"
        echo ""
        echo "请选择操作："
        echo "  1) 启动穿透"
        echo "  2) 停止穿透"
        echo "  3) 设置设备ID"
        echo "  4) 穿透日志管理"
        echo "  5) 下载/更新客户端"
        echo "  6) 删除客户端"
        echo "  7) 查看帮助信息"
        echo "  0) 返回主菜单"
        echo ""

        echo -n "请输入选项编号 [0-7]: "
        read -r choice

        # 处理空输入
        if [ -z "$choice" ]; then
            echo ""
            continue
        fi

        case "$choice" in
            1)
                echo ""
                echo ">>> 正在启动穿透服务..."
                echo ""
                start_hp_service
                echo ""
                echo "按回车键返回..."
                read
                ;;
            2)
                echo ""
                echo ">>> 正在停止穿透服务..."
                echo ""
                stop_hp_service
                echo ""
                echo "按回车键返回..."
                read
                ;;
            3)
                echo ""
                echo ">>> 进入设置设备ID..."
                echo ""
                cli_set_device_id
                echo ""
                echo "按回车键返回..."
                read
                ;;
            4)
                echo ""
                echo ">>> 进入日志管理..."
                echo ""
                cli_hp_log_menu
                echo ""
                echo "按回车键返回..."
                read
                ;;
            5)
                echo ""
                echo ">>> 正在下载/更新客户端..."
                echo ""
                download_hp_client
                echo ""
                echo "按回车键返回..."
                read
                ;;
            6)
                echo ""
                echo ">>> 正在删除客户端..."
                echo ""
                delete_hp_client
                echo ""
                echo "按回车键返回..."
                read
                ;;
            7)
                echo ""
                echo ">>> 正在打开帮助信息..."
                echo ""
                cli_show_hp_help
                echo ""
                echo "按回车键返回..."
                read
                ;;
            0)
                echo ""
                echo "返回主菜单..."
                echo ""
                break
                ;;
            *)
                echo ""
                echo -e "${RED}无效选项 '$choice'，请重新输入${NC}"
                echo ""
                ;;
        esac
    done
}

# CLI 设置设备ID
cli_set_device_id() {
    # 直接调用 set_device_id 函数，它会处理输入
    set_device_id
}

# CLI 日志管理菜单
cli_hp_log_menu() {
    while true; do
        echo ""
        echo "=== 穿透日志管理 ==="
        echo ""

        # 获取日志文件信息
        local log_info="无日志文件"
        if [ -f "$HP_LOG_FILE" ]; then
            local log_size=$(du -h "$HP_LOG_FILE" | cut -f1)
            local log_lines=$(wc -l < "$HP_LOG_FILE" 2>/dev/null || echo "未知")
            log_info="${log_lines}行, ${log_size}"
        fi

        echo "日志文件: $log_info"
        echo ""
        echo "请选择操作："
        echo "  1) 查看日志"
        echo "  2) 清空日志"
        echo "  0) 返回"
        echo ""

        echo -n "请选择 [0-2]: "
        read -r choice

        case "$choice" in
            1)
                if [ -f "$HP_LOG_FILE" ]; then
                    ui_pager "HPPRO 日志" "$(tail -100 "$HP_LOG_FILE")"
                else
                    echo "日志文件不存在"
                fi
                ;;
            2)
                if ui_confirm "确定要清空 HPPRO 日志文件吗？此操作不可恢复！"; then
                    > "$HP_LOG_FILE"
                    echo "日志已清空"
                fi
                ;;
            0)
                return
                ;;
            *)
                echo -e "${RED}无效选项，请重新选择${NC}"
                ;;
        esac
    done
}

# CLI 显示 HPPRO 帮助
cli_show_hp_help() {
    local help_content="
HPPRO 内网穿透使用说明

1. 首次使用需要：
   - 设置设备ID（在穿透官网注册获取）
   - 下载客户端

2. 使用流程：
   - 启动穿透服务
   - 记录显示的映射地址
   - 将地址分享给玩家

3. 常见问题：
   - 穿透无法连接：检查设备ID是否正确
   - 端口不通：检查服务器是否启动
   - 日志报错：查看日志详情

更多信息请访问: https://www.hpproxy.cn
"
    ui_pager "HPPRO 帮助信息" "$help_content"
}


# 打开HPPRO官网
open_hp_website() {
    local hp_website="https://www.hpproxy.cn/#/"  # 根据链接1设置的官网

    # 显示官网信息并提供打开选项
    if [ "$NO_GUI" = "true" ]; then
        echo ""
        echo "HPPRO 官网: $hp_website"
        if cli_yes_no "是否立即在浏览器中打开官网？"; then
            # 尝试用系统默认浏览器打开
            if command -v xdg-open >/dev/null 2>&1; then
                xdg-open "$hp_website" &
            elif command -v open >/dev/null 2>&1; then
                open "$hp_website" &
            elif command -v start >/dev/null 2>&1; then
            # Windows系统（如果通过WSL运行）
            start "$hp_website" &
        else
            # 无法自动打开，显示链接
            show_msg "浏览器打开" "无法自动打开浏览器，请手动访问:\n$hp_website"
            return
            fi

            # 检查是否打开成功
            if [ $? -eq 0 ]; then
                show_msg "成功" "正在浏览器中打开官网..."
            else
                show_msg "提示" "请手动访问官网:\n$hp_website"
            fi
        else
            # 用户选择不打开，显示链接信息
            show_msg "官网信息" "HPPRO官网: $hp_website\n\n您可以在浏览器中手动访问该网址。"
        fi
    else
        # GUI 模式
        if safe_whiptail --title "HPPRO 官网信息" \
            --yesno "是否立即在浏览器中打开官网？" 10 50; then

            # 尝试用系统默认浏览器打开
            if command -v xdg-open >/dev/null 2>&1; then
                # Linux系统
                xdg-open "$hp_website" &
            elif command -v open >/dev/null 2>&1; then
                # macOS系统
                open "$hp_website" &
            elif command -v start >/dev/null 2>&1; then
                # Windows系统
                start "$hp_website"
            else
                show_msg "错误" "无法自动打开浏览器，请手动访问:\n$hp_website"
                return 1
            fi

            # 检查是否打开成功
            if [ $? -eq 0 ]; then
                show_msg "成功" "正在浏览器中打开官网..."
            else
                show_msg "提示" "请手动访问官网:\n$hp_website"
            fi
        else
            # 用户选择不打开，显示链接信息
            show_msg "官网信息" "HPPRO官网: $hp_website\n\n您可以在浏览器中手动访问该网址。"
        fi
    fi
}

# 初始化HPPRO配置
init_hp_config() {
    HP_DIR="$CONFIG_DIR/hppro"
    mkdir -p "$HP_DIR"
    
    # 从配置文件加载HPPRO设置
    if [ -f "$CONFIG_FILE" ]; then
        HP_DEVICE_ID=$(jq -r '.hppro.device_id' "$CONFIG_FILE")
        HP_DOWNLOADED=$(jq -r '.hppro.downloaded' "$CONFIG_FILE")
    else
        HP_DEVICE_ID=""
        HP_DOWNLOADED="false"
    fi
}

# 保存HPPRO配置
save_hp_config() {
    local temp_file="$CONFIG_FILE.tmp"
    
    jq --arg device_id "$HP_DEVICE_ID" \
       --argjson downloaded "$HP_DOWNLOADED" \
       '.hppro.device_id = $device_id |
        .hppro.downloaded = $downloaded' \
       "$CONFIG_FILE" > "$temp_file" && mv "$temp_file" "$CONFIG_FILE"
}

# 检查HPPRO是否运行
is_hp_running() {
    # 检查PID文件
    if [ -f "$HP_DIR/hp-client.pid" ]; then
        local pid=$(cat "$HP_DIR/hp-client.pid")
        if ps -p "$pid" > /dev/null 2>&1; then
            return 0
        else
            # 清理无效的PID文件
            rm -f "$HP_DIR/hp-client.pid"
        fi
    fi
    
    # 检查进程列表
    if pgrep -f "hp-client" > /dev/null 2>&1; then
        return 0
    fi
    
    return 1
}

# 检查HPPRO客户端是否已下载
is_hp_client_downloaded() {
    if [ "$HP_DOWNLOADED" = "true" ] && [ -f "$HP_DIR/hp-client" ]; then
        return 0
    else
        return 1
    fi
}

# 启动HPPRO服务
start_hp_service() {
    # 检查客户端是否已下载
    if ! is_hp_client_downloaded; then
        show_msg "错误" "HPPRO客户端未下载，请先下载客户端"
        return 1
    fi
    
    # 检查设备ID是否设置
    if [ -z "$HP_DEVICE_ID" ]; then
        show_msg "错误" "设备ID未设置，请先设置设备ID"
        return 1
    fi
    
    # 检查是否已运行
    if is_hp_running; then
        show_msg "信息" "HPPRO服务已经在运行中"
        return 0
    fi
    
    # 停止可能存在的旧进程
    stop_hp_service
    
    # 启动HPPRO服务
    show_msg "启动中" "正在启动HPPRO服务..."
    cd "$HP_DIR"
    nohup ./hp-client -deviceId="$HP_DEVICE_ID" > hp-client.log 2>&1 &
    HP_PID=$!
    
    # 保存PID
    echo $HP_PID > "$HP_DIR/hp-client.pid"
    
    # 等待几秒检查是否启动成功
    sleep 2
    if ps -p $HP_PID > /dev/null 2>&1; then
        show_msg "成功" "HPPRO服务已启动 (PID: $HP_PID)"
        return 0
    else
        show_msg "错误" "HPPRO服务启动失败，请查看日志"
        rm -f "$HP_DIR/hp-client.pid"
        return 1
    fi
}

# 删除HPPRO客户端
delete_hp_client() {
    # 检查客户端是否已下载
    if [ ! -f "$HP_DIR/hp-client" ]; then
        show_msg "信息" "HPPRO客户端未下载，无需删除"
        return 0
    fi

    # 检查是否正在运行
    if is_hp_running; then
        show_msg "错误" "HPPRO服务正在运行，请先停止服务"
        return 1
    fi

    # 确认删除
    if ui_confirm "确定要删除HPPRO客户端吗？此操作不可恢复！"; then
        rm -f "$HP_DIR/hp-client"
        HP_DOWNLOADED="false"
        save_hp_config
        show_msg "成功" "HPPRO客户端已删除"
    fi
}

# 停止HPPRO服务
stop_hp_service() {
    # 检查PID文件是否存在
    if [ ! -f "$HP_DIR/hp-client.pid" ]; then
        # 尝试查找并停止所有hp-client进程
        PIDS=$(pgrep -f "hp-client")
        if [ -n "$PIDS" ]; then
            kill $PIDS 2>/dev/null
            show_msg "成功" "已停止所有HPPRO进程"
        else
            show_msg "信息" "没有找到运行的HPPRO进程"
        fi
        return
    fi
    
    # 从PID文件获取进程ID
    local pid=$(cat "$HP_DIR/hp-client.pid")
    
    # 停止进程
    if kill "$pid" 2>/dev/null; then
        rm -f "$HP_DIR/hp-client.pid"
        show_msg "成功" "HPPRO服务已停止"
    else
        # 如果停止失败，尝试强制停止
        if kill -9 "$pid" 2>/dev/null; then
            rm -f "$HP_DIR/hp-client.pid"
            show_msg "成功" "HPPRO服务已强制停止"
        else
            show_msg "错误" "无法停止HPPRO服务"
        fi
    fi
}

# 设置设备ID
set_device_id() {
    # 获取当前设备ID
    local current_id=$HP_DEVICE_ID
    
    # 输入新的设备ID
    if [ -n "$current_id" ]; then
        new_id=$(ui_input "当前设备ID: $current_id
请输入新的设备ID")
    else
        new_id=$(ui_input "请输入设备ID")
    fi
    
    if [ -z "$new_id" ]; then
        show_msg "错误" "设备ID不能为空"
        return
    fi
    
    # 更新设备ID
    HP_DEVICE_ID=$new_id
    save_hp_config
    
    show_msg "成功" "设备ID已设置为: $new_id"
}

# 下载/更新HPPRO客户端
download_hp_client() {
    ui_confirm "确定要下载/更新客户端吗？"
    [ $? -ne 0 ] && return

    # 确定下载URL（优先使用备用URL）
    local hp_url backup_url
    case "$ARCH" in
        x86_64|amd64)
            hp_url="http://download.hycexit.xyz/hppro/hp-pro-amd64"
            backup_url="https://www.hpproxy.cn/bin/hp-pro-amd64"
            ;;
        aarch64|arm64)
            hp_url="http://download.hycexit.xyz/hppro/hp-pro-arm64"
            backup_url="https://www.hpproxy.cn/bin/hp-pro-arm64"
            ;;
        armv7l|armv7)
            hp_url="http://download.hycexit.xyz/hppro/hp-pro-armv7"
            backup_url="https://www.hpproxy.cn/bin/hp-pro-armv7"
            ;;
        i686|i386|386)
            hp_url="http://download.hycexit.xyz/hppro/hp-pro-386"
            backup_url="https://www.hpproxy.cn/bin/hp-pro-386"
            ;;
        *)
            show_msg "错误" "不支持的架构: $ARCH"
            return 1
            ;;
    esac

    echo -e "${BLUE}使用架构: $ARCH -> 下载URL: $hp_url${NC}"

    # 下载HPPRO客户端
    if download_with_progress "$hp_url" "$HP_DIR/hp-client" "正在下载" "HPPRO客户端..."; then
        # 设置执行权限
        chmod +x "$HP_DIR/hp-client"

        # 标记为已下载
        HP_DOWNLOADED="true"
        save_hp_config

        echo -e "${GREEN}HPPRO客户端下载完成${NC}"
        return 0
    else
        echo -e "${RED}HPPRO客户端下载失败，尝试备用URL...${NC}"

        # 尝试备用URL

        if [ -n "$backup_url" ]; then
            echo -e "${BLUE}备用URL: $backup_url${NC}"
            if download_with_progress "$backup_url" "$HP_DIR/hp-client" "正在下载" "HPPRO客户端(备用)..."; then
                chmod +x "$HP_DIR/hp-client"
                HP_DOWNLOADED="true"
                save_hp_config
                echo -e "${GREEN}HPPRO客户端下载完成${NC}"
                return 0
            fi
        fi

        echo -e "${RED}HPPRO客户端下载失败${NC}"
        return 1
    fi
}

# 日志管理菜单
hp_log_menu() {
    while true; do
        # 获取日志文件状态
        local log_status="无日志文件"
        if [ -f "$HP_LOG_FILE" ]; then
            local log_size=$(du -h "$HP_LOG_FILE" | cut -f1)
            local log_lines=$(wc -l < "$HP_LOG_FILE" 2>/dev/null || echo "未知")
            log_status="$log_lines 行, $log_size"
        fi
        
        choice=$(safe_whiptail --nocancel --clear \
            --title "HPPRO 日志管理" \
            --menu "日志状态: $log_status\n\n请选择操作：" 18 60 8 \
            "1" "实时监控日志" \
            "2" "less查看日志" \
            "3" "查看日志快照" \
            "4" "搜索日志内容" \
            "5" "查看统计信息" \
            "6" "导出日志文件" \
            "7" "清空日志文件" \
            "0" "返回上级菜单" \
            3>&1 1>&2 2>&3)
        
        case $choice in
            1) view_hp_realtime_logs ;;
            2) view_hp_logs_with_less ;;
            3) view_hp_log_snapshot ;;
            4) search_hp_logs ;;
            5) show_log_statistics ;;
            6) export_hp_logs ;;
            7) clear_hp_logs ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 实时监控日志
view_hp_realtime_logs() {
    if [ ! -f "$HP_LOG_FILE" ]; then
        show_msg "信息" "没有可用的日志文件"
        return
    fi
    
    # 保存当前终端设置
    local original_stty=$(stty -g 2>/dev/null)
    
    # 结束图形界面，恢复终端
    exec 3>&-
    exec 4>&-
    clear
    
    echo -e "${BLUE}实时监控 HPPRO 日志${NC}"
    echo -e "${YELLOW}正在实时显示日志内容，按 Ctrl+C 停止并返回菜单...${NC}"
    echo "=========================================="
    
    # 显示最后几行日志作为上下文
    tail -20 "$HP_LOG_FILE"
    echo "=========================================="
    echo -e "${GREEN}以上是历史日志，下面开始实时跟踪:${NC}"
    
    # 使用 tail -f 实时显示日志
    tail -f "$HP_LOG_FILE" &
    local tail_pid=$!
    
    # 设置信号处理
    trap 'echo -e "\n${YELLOW}停止实时查看...${NC}"; kill $tail_pid 2>/dev/null; exit 130' INT TERM
    
    # 等待用户中断
    wait $tail_pid 2>/dev/null
    
    # 清理
    kill $tail_pid 2>/dev/null
    restore_terminal_settings
    export IN_LOG_VIEW_MODE="false"
    
    echo -e "${GREEN}实时日志查看已停止${NC}"
    echo -e "${YELLOW}按任意键返回日志管理菜单...${NC}"
    read -n 1 -s
    
    # 返回日志管理菜单
    exec "$SCRIPT_PATH" --skip-welcome --goto-menu "hp_log_menu"
    
}

# 使用 less 查看日志
view_hp_logs_with_less() {
    if [ ! -f "$HP_LOG_FILE" ]; then
        show_msg "信息" "没有可用的日志文件"
        return
    fi
    
    # 保存当前终端设置
    local original_stty=$(stty -g 2>/dev/null)
    
    # 结束图形界面，恢复终端
    exec 3>&-
    exec 4>&-
    clear
    
    echo -e "${BLUE}使用 less 查看 HPPRO 日志${NC}"
    echo -e "${YELLOW}使用说明:${NC}"
    echo -e "${YELLOW}  - 按 F 键进入实时跟踪模式${NC}"
    echo -e "${YELLOW}  - 按 Ctrl+C 退出跟踪模式${NC}"
    echo -e "${YELLOW}  - 按 / 键搜索关键词${NC}"
    echo -e "${YELLOW}  - 按 q 键退出日志查看${NC}"
    echo -e "${YELLOW}按任意键开始查看...${NC}"
    read -n 1 -s
    
    # 使用 less 查看日志文件
    if ! less -R +F "$HP_LOG_FILE"; then
        echo -e "${YELLOW}less 命令执行异常，使用备用方式...${NC}"
        cat "$HP_LOG_FILE"
        echo -e "${YELLOW}按任意键继续...${NC}"
        read -n 1 -s
    fi
    
    # 恢复终端设置
    stty "$original_stty" 2>/dev/null
    
    # 查看完成后提供选项
    echo -e "${GREEN}日志查看已完成${NC}"
    echo -e "${YELLOW}请选择下一步操作：${NC}"
    echo "1. 再次查看日志"
    echo "2. 返回日志管理菜单"
    echo "3. 返回主菜单"
    echo -n "请输入选择 (1-3): "
    
    read -r choice
    case $choice in
        1)
            view_hp_logs_with_less
            ;;
        2)
            # 返回日志管理菜单
            exec "$SCRIPT_PATH" --skip-welcome --goto-menu "hp_log_menu"
            ;;
        3)
            # 返回主菜单
            exec "$SCRIPT_PATH" --skip-welcome
            ;;
        *)
            echo -e "${RED}无效选择，返回日志管理菜单${NC}"
            exec "$SCRIPT_PATH" --skip-welcome --goto-menu "hp_log_menu"
            ;;
    esac
}

# 查看日志快照（当前内容）
view_hp_log_snapshot() {
    if [ ! -f "$HP_LOG_FILE" ]; then
        show_msg "信息" "没有可用的日志文件"
        return
    fi
    
    # 获取日志文件信息
    local log_size=$(du -h "$HP_LOG_FILE" | cut -f1)
    local log_lines=$(wc -l < "$HP_LOG_FILE" 2>/dev/null || echo "未知")
    local log_mtime=$(stat -c "%y" "$HP_LOG_FILE" | cut -d. -f1)
    
    # 保存当前终端设置
    local original_stty=$(stty -g)
    
    # 结束图形界面，恢复终端
    exec 3>&-
    exec 4>&-
    clear
    
    echo -e "${BLUE}HPPRO 日志快照${NC}"
    echo "=========================================="
    echo -e "文件: $(basename "$HP_LOG_FILE")"
    echo -e "大小: $log_size"
    echo -e "行数: $log_lines"
    echo -e "修改时间: $log_mtime"
    echo "=========================================="
    
    # 显示日志内容（最后100行）
    if [ "$log_lines" -gt 100 ]; then
        echo -e "${YELLOW}显示最后100行日志（共$log_lines行）:${NC}"
        tail -100 "$HP_LOG_FILE"
    else
        cat "$HP_LOG_FILE"
    fi
    
    echo "=========================================="
    echo -e "${YELLOW}按任意键返回...${NC}"
    read -n 1 -s
    
    # 恢复终端设置
    stty "$original_stty"
    
    # 返回日志管理菜单
    hp_log_menu
}

# 搜索日志内容
search_hp_logs() {
    if [ ! -f "$HP_LOG_FILE" ]; then
        show_msg "信息" "没有可用的日志文件"
        return
    fi
    
    # 获取搜索关键词
    local search_term=$(ui_input "请输入要搜索的关键词")
    [ -z "$search_term" ] && return
    
    # 保存当前终端设置
    local original_stty=$(stty -g)
    
    # 结束图形界面，恢复终端
    exec 3>&-
    exec 4>&-
    clear
    
    echo -e "${BLUE}在 HPPRO 日志中搜索: '$search_term'${NC}"
    echo "=========================================="
    
    # 搜索并显示结果
    local results=$(grep -n -i "$search_term" "$HP_LOG_FILE" 2>/dev/null)
    
    if [ -n "$results" ]; then
        echo "$results"
        local result_count=$(echo "$results" | wc -l)
        echo "=========================================="
        echo -e "${GREEN}找到 $result_count 个匹配项${NC}"
    else
        echo -e "${YELLOW}未找到匹配项${NC}"
    fi
    
    echo "=========================================="
    echo -e "${YELLOW}按任意键返回...${NC}"
    read -n 1 -s
    
    # 恢复终端设置
    stty "$original_stty"
    
    # 返回日志管理菜单
    hp_log_menu
}

# 查看统计信息
show_log_statistics() {
    if [ ! -f "$HP_LOG_FILE" ]; then
        show_msg "信息" "没有可用的日志文件"
        return
    fi
    
    # 获取日志统计信息
    local total_lines=$(wc -l < "$HP_LOG_FILE" 2>/dev/null || echo 0)
    local error_count=$(grep -c -i "error\|fail\|failed" "$HP_LOG_FILE" 2>/dev/null || echo 0)
    local warning_count=$(grep -c -i "warn" "$HP_LOG_FILE" 2>/dev/null || echo 0)
    local connection_count=$(grep -c -i "connect" "$HP_LOG_FILE" 2>/dev/null || echo 0)
    local last_error=$(grep -i "error\|fail\|failed" "$HP_LOG_FILE" | tail -1 2>/dev/null || echo "无")
    local log_size=$(du -h "$HP_LOG_FILE" | cut -f1)
    local log_mtime=$(stat -c "%y" "$HP_LOG_FILE" | cut -d. -f1)
    
    # 计算错误率
    local error_rate="0"
    if [ "$total_lines" -gt 0 ]; then
        error_rate=$(echo "scale=2; $error_count * 100 / $total_lines" | bc)
    fi
    
    # 显示统计信息
    local stats="HPPRO 日志统计信息\n\n"
    stats+="总行数: $total_lines\n"
    stats+="文件大小: $log_size\n"
    stats+="修改时间: $log_mtime\n"
    stats+="错误数量: $error_count\n"
    stats+="警告数量: $warning_count\n"
    stats+="连接相关: $connection_count\n"
    stats+="错误率: $error_rate%\n\n"
    stats+="最近错误: $last_error"
    
    ui_message "日志统计信息" "$stats"
}

# 导出日志文件
export_hp_logs() {
    if [ ! -f "$HP_LOG_FILE" ]; then
        show_msg "信息" "没有可用的日志文件"
        return
    fi
    
    # 获取导出路径
    local default_path="$HOME/Downloads/hppro_log_$(date +%Y%m%d_%H%M%S).log"
    local export_path=$(ui_input "请输入导出路径" "$default_path")
    [ -z "$export_path" ] && return
    
    # 检查目标目录是否存在
    local export_dir=$(dirname "$export_path")
    if [ ! -d "$export_dir" ]; then
        ui_confirm "目录不存在，是否创建？"
        if [ $? -eq 0 ]; then
            mkdir -p "$export_dir" || {
                show_msg "错误" "无法创建目录: $export_dir"
                return
            }
        else
            return
        fi
    fi
    
    # 导出日志
    if cp "$HP_LOG_FILE" "$export_path"; then
        show_msg "成功" "日志已导出到: $export_path"
    else
        show_msg "错误" "导出失败"
    fi
}

# 清空日志文件
clear_hp_logs() {
    if [ ! -f "$HP_LOG_FILE" ]; then
        show_msg "信息" "没有日志文件可清空"
        return
    fi
    
    # 确认操作
    ui_confirm "确定要清空 HPPRO 日志文件吗？此操作不可恢复！"
    if [ $? -ne 0 ]; then
        return
    fi
    
    # 备份当前日志
    local backup_file="$HP_DIR/hp-client.log.backup.$(date +%Y%m%d_%H%M%S)"
    if cp "$HP_LOG_FILE" "$backup_file"; then
        # 清空日志文件
        > "$HP_LOG_FILE"
        show_msg "成功" "日志已清空\n原日志已备份到: $(basename "$backup_file")"
    else
        show_msg "错误" "备份失败，无法清空日志"
    fi
}

# 系统设置功能

# 系统设置菜单
system_settings() {
    # CLI 模式调用 CLI 版本
    if [ "$NO_GUI" = "true" ]; then
        cli_system_settings
        return
    fi

    while true; do
        choice=$(safe_whiptail --nocancel --clear \
            --title "系统设置" \
            --menu "请选择操作：" 20 60 10 \
            "1" "检查脚本更新" \
            "2" "查看系统信息" \
            "3" "检查JDK环境" \
            "4" "清理缓存文件" \
            "0" "返回主菜单" \
            3>&1 1>&2 2>&3)

        case $choice in
            1) update_manager ;;
            2) show_system_info ;;
            3) check_and_repair_jdk_environment ;;
            4) cleanup_cache_files ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# ============================================
# CLI 系统设置菜单
# ============================================

cli_system_settings() {
    while true; do
        # 清屏
        clear 2>/dev/null || printf "\033[2J\033[H"

        echo ""
        echo "============================================"
        echo "           系统设置"
        echo "============================================"
        echo ""
        echo "  1) 检查脚本更新    - 检查并更新管理器版本"
        echo "  2) 查看系统信息    - 查看服务器系统信息"
        echo "  3) 检查 JDK 环境   - 检查并修复 JDK 配置"
        echo "  4) 清理缓存文件    - 清理临时文件和日志"
        echo "  0) 返回主菜单"
        echo ""
        echo "--------------------------------------------"

        echo -n "请输入选项编号 [0-4]: "
        read -r choice

        # 处理空输入
        if [ -z "$choice" ]; then
            echo ""
            continue
        fi

        case "$choice" in
            1)
                echo ""
                echo ">>> 正在检查更新..."
                echo ""
                update_manager
                echo ""
                echo "按回车键返回..."
                read
                ;;
            2)
                echo ""
                echo ">>> 正在获取系统信息..."
                echo ""
                cli_show_system_info
                echo ""
                echo "按回车键返回..."
                read
                ;;
            3)
                echo ""
                echo ">>> 正在检查 JDK 环境..."
                echo ""
                check_and_repair_jdk_environment
                echo ""
                echo "按回车键返回..."
                read
                ;;
            4)
                echo ""
                echo ">>> 进入清理缓存..."
                echo ""
                cli_cleanup_cache_files
                echo ""
                echo "按回车键返回..."
                read
                ;;
            0)
                echo ""
                echo "返回主菜单..."
                echo ""
                break
                ;;
            *)
                echo ""
                echo -e "${RED}无效选项 '$choice'，请重新输入${NC}"
                echo ""
                ;;
        esac
    done
}

# CLI 显示系统信息
cli_show_system_info() {
    show_system_info
}

# CLI 清理缓存文件
cli_cleanup_cache_files() {
    local cache_size=$(du -sh "$CONFIG_DIR" 2>/dev/null | cut -f1)
    local temp_files=0

    # 查找临时文件
    temp_files=$(find "$CONFIG_DIR" -name "*.tmp" -o -name "*.backup.*" -o -name "*.log.*" 2>/dev/null | wc -l)

    echo ""
    echo "=== 清理缓存文件 ==="
    echo ""
    echo "缓存目录: $CONFIG_DIR"
    echo "缓存大小: ${cache_size:-未知}"
    echo "临时文件: ${temp_files} 个"
    echo ""

    if [ "$temp_files" -gt 0 ]; then
        if ui_confirm "确定要清理 $temp_files 个临时文件吗？"; then
            find "$CONFIG_DIR" -name "*.tmp" -o -name "*.backup.*" -o -name "*.log.*" -delete 2>/dev/null
            echo "清理完成"
        fi
    else
        echo "没有需要清理的文件"
        echo -n "按回车键返回... "
        read -r
    fi
}

# 清理缓存文件函数
cleanup_cache_files() {
    # CLI 模式调用 CLI 版本
    if [ "$NO_GUI" = "true" ]; then
        cli_cleanup_cache_files
        return
    fi

    local cache_size=$(du -sh "$CONFIG_DIR" 2>/dev/null | cut -f1)
    local temp_files=0

    # 查找临时文件
    temp_files=$(find "$CONFIG_DIR" -name "*.tmp" -o -name "*.backup.*" -o -name "*.log.*" 2>/dev/null | wc -l)

    # 显示清理选项
    choice=$(safe_whiptail --title "清理缓存文件" \
        --menu "当前缓存大小: $cache_size\n临时文件数量: $temp_files\n\n选择清理选项：" \
        18 60 6 \
        "1" "清理临时文件 (*.tmp, *.backup.*)" \
        "2" "清理旧日志文件 (*.log.*)" \
        "3" "清理下载缓存" \
        "4" "清理所有缓存" \
        "5" "查看缓存详情" \
        "0" "返回" \
        3>&1 1>&2 2>&3)
    
    case $choice in
        1)
            cleanup_temporary_files
            ;;
        2)
            cleanup_old_logs
            ;;
        3)
            cleanup_download_cache
            ;;
        4)
            cleanup_all_cache
            ;;
        5)
            show_cache_details
            ;;
        0)
            return
            ;;
        *)
            show_msg "错误" "无效选项"
            ;;
    esac
}

# 清理临时文件
cleanup_temporary_files() {
    local temp_files=$(find "$CONFIG_DIR" \( -name "*.tmp" -o -name "*.backup.*" -o -name "*.bak" \) -type f 2>/dev/null)
    local temp_count=0
    local freed_space=0
    
    if [ -n "$temp_files" ]; then
        temp_count=$(echo "$temp_files" | wc -l)
        
        # 计算总大小
        while IFS= read -r file; do
            if [ -f "$file" ]; then
                freed_space=$((freed_space + $(stat -c%s "$file" 2>/dev/null || echo 0)))
            fi
        done <<< "$temp_files"
        
        ui_confirm "确定要清理 $temp_count 个临时文件吗？\n\n预计释放空间: $(echo "scale=2; $freed_space/1024/1024" | bc)MB"
        if [ $? -eq 0 ]; then
            echo "$temp_files" | while read -r file; do
                rm -f "$file" 2>/dev/null && echo "已删除: $file"
            done
            
            local freed_mb=$(echo "scale=2; $freed_space/1024/1024" | bc)
            show_msg "成功" "已清理 $temp_count 个临时文件\n释放空间: ${freed_mb}MB"
        fi
    else
        show_msg "信息" "没有找到临时文件"
    fi
}

# 清理旧日志文件
cleanup_old_logs() {
    local log_files=$(find "$CONFIG_DIR" -name "*.log.*" -type f 2>/dev/null)
    local log_count=0
    local freed_space=0
    
    # 按日期分类日志文件
    local today=$(date +%Y%m%d)
    local keep_days=7  # 保留最近7天的日志
    
    if [ -n "$log_files" ]; then
        log_count=$(echo "$log_files" | wc -l)
        
        # 计算可清理的文件
        local files_to_clean=()
        while IFS= read -r file; do
            if [ -f "$file" ]; then
                local file_date=$(stat -c "%y" "$file" | cut -d' ' -f1 | sed 's/-//g')
                local days_old=$(( (today - file_date) ))
                
                if [ $days_old -gt $keep_days ]; then
                    files_to_clean+=("$file")
                    freed_space=$((freed_space + $(stat -c%s "$file" 2>/dev/null || echo 0)))
                fi
            fi
        done <<< "$log_files"
        
        local clean_count=${#files_to_clean[@]}
        
        if [ $clean_count -gt 0 ]; then
            ui_confirm "找到 $clean_count 个超过${keep_days}天的旧日志文件\n\n确定要清理吗？\n预计释放空间: $(echo "scale=2; $freed_space/1024/1024" | bc)MB"
            if [ $? -eq 0 ]; then
                for file in "${files_to_clean[@]}"; do
                    rm -f "$file" 2>/dev/null && echo "已删除: $file"
                done
                
                local freed_mb=$(echo "scale=2; $freed_space/1024/1024" | bc)
                show_msg "成功" "已清理 $clean_count 个旧日志文件\n释放空间: ${freed_mb}MB"
            fi
        else
            show_msg "信息" "没有找到超过${keep_days}天的旧日志文件"
        fi
    else
        show_msg "信息" "没有找到可清理的日志文件"
    fi
}

# 清理下载缓存
cleanup_download_cache() {
    local cache_dirs=("$MCJDK_DIR" "$HP_DIR" "$CONFIG_DIR/cache")
    local total_freed=0
    local total_count=0
    
    for cache_dir in "${cache_dirs[@]}"; do
        if [ -d "$cache_dir" ]; then
            # 查找下载的临时文件
            local cache_files=$(find "$cache_dir" -name "*.tmp" -o -name "*.part" -o -name "*.download" -type f 2>/dev/null)
            local dir_freed=0
            local dir_count=0
            
            while IFS= read -r file; do
                if [ -f "$file" ]; then
                    dir_freed=$((dir_freed + $(stat -c%s "$file" 2>/dev/null || echo 0)))
                    ((dir_count++))
                    rm -f "$file" 2>/dev/null
                fi
            done <<< "$cache_files"
            
            if [ $dir_count -gt 0 ]; then
                echo "清理 $cache_dir: $dir_count 个文件, $(echo "scale=2; $dir_freed/1024/1024" | bc)MB"
                total_freed=$((total_freed + dir_freed))
                total_count=$((total_count + dir_count))
            fi
        fi
    done
    
    if [ $total_count -gt 0 ]; then
        local total_mb=$(echo "scale=2; $total_freed/1024/1024" | bc)
        show_msg "成功" "已清理 $total_count 个下载缓存文件\n释放空间: ${total_mb}MB"
    else
        show_msg "信息" "没有找到下载缓存文件"
    fi
}

# 清理所有缓存
cleanup_all_cache() {
    ui_confirm "确定要清理所有缓存文件吗？\n\n这将包括:\n• 临时文件\n• 旧日志文件\n• 下载缓存\n• 备份文件\n\n此操作不可恢复！"
    if [ $? -ne 0 ]; then
        return
    fi
    
    local total_freed=0
    local total_count=0
    
    # 清理各种类型的缓存
    echo -e "${BLUE}开始清理所有缓存...${NC}"
    
    # 1. 临时文件
    local temp_files=$(find "$CONFIG_DIR" \( -name "*.tmp" -o -name "*.backup.*" -o -name "*.bak" \) -type f 2>/dev/null)
    while IFS= read -r file; do
        if [ -f "$file" ]; then
            total_freed=$((total_freed + $(stat -c%s "$file" 2>/dev/null || echo 0)))
            rm -f "$file" 2>/dev/null
            ((total_count++))
        fi
    done <<< "$temp_files"
    
    # 2. 旧日志文件（保留最近3天）
    local today=$(date +%Y%m%d)
    local log_files=$(find "$CONFIG_DIR" -name "*.log.*" -type f 2>/dev/null)
    while IFS= read -r file; do
        if [ -f "$file" ]; then
            local file_date=$(stat -c "%y" "$file" | cut -d' ' -f1 | sed 's/-//g')
            local days_old=$(( (today - file_date) ))
            
            if [ $days_old -gt 3 ]; then  # 只清理3天前的日志
                total_freed=$((total_freed + $(stat -c%s "$file" 2>/dev/null || echo 0)))
                rm -f "$file" 2>/dev/null
                ((total_count++))
            fi
        fi
    done <<< "$log_files"
    
    # 3. 下载缓存
    local cache_dirs=("$MCJDK_DIR" "$HP_DIR" "$CONFIG_DIR/cache")
    for cache_dir in "${cache_dirs[@]}"; do
        if [ -d "$cache_dir" ]; then
            local cache_files=$(find "$cache_dir" -name "*.tmp" -o -name "*.part" -o -name "*.download" -type f 2>/dev/null)
            while IFS= read -r file; do
                if [ -f "$file" ]; then
                    total_freed=$((total_freed + $(stat -c%s "$file" 2>/dev/null || echo 0)))
                    rm -f "$file" 2>/dev/null
                    ((total_count++))
                fi
            done <<< "$cache_files"
        fi
    done
    
    # 4. 清理空的备份目录
    local backup_dirs=$(find "$CONFIG_DIR" -name "*.backup" -type d 2>/dev/null)
    while IFS= read -r dir; do
        if [ -d "$dir" ] && [ -z "$(ls -A "$dir")" ]; then
            rmdir "$dir" 2>/dev/null && ((total_count++))
        fi
    done <<< "$backup_dirs"
    
    local total_mb=$(echo "scale=2; $total_freed/1024/1024" | bc)
    show_msg "成功" "缓存清理完成！\n\n已清理文件: $total_count 个\n释放空间: ${total_mb}MB\n\n系统缓存已优化。"
}

# 显示缓存详情
show_cache_details() {
    local details="=== 缓存文件详情 ===\n\n"
    local total_size=0
    local total_files=0
    
    # 临时文件
    local temp_files=$(find "$CONFIG_DIR" \( -name "*.tmp" -o -name "*.backup.*" -o -name "*.bak" \) -type f 2>/dev/null)
    local temp_count=0
    local temp_size=0
    
    while IFS= read -r file; do
        if [ -f "$file" ]; then
            temp_size=$((temp_size + $(stat -c%s "$file" 2>/dev/null || echo 0)))
            ((temp_count++))
        fi
    done <<< "$temp_files"
    
    details+="📁 临时文件: $temp_count 个, $(echo "scale=2; $temp_size/1024/1024" | bc)MB\n"
    total_size=$((total_size + temp_size))
    total_files=$((total_files + temp_count))
    
    # 日志文件
    local log_files=$(find "$CONFIG_DIR" -name "*.log.*" -type f 2>/dev/null)
    local log_count=0
    local log_size=0
    local today=$(date +%Y%m%d)
    
    while IFS= read -r file; do
        if [ -f "$file" ]; then
            local file_size=$(stat -c%s "$file" 2>/dev/null || echo 0)
            log_size=$((log_size + file_size))
            ((log_count++))
        fi
    done <<< "$log_files"
    
    details+="📊 日志文件: $log_count 个, $(echo "scale=2; $log_size/1024/1024" | bc)MB\n"
    total_size=$((total_size + log_size))
    total_files=$((total_files + log_count))
    
    # 下载缓存
    local cache_dirs=("$MCJDK_DIR" "$HP_DIR" "$CONFIG_DIR/cache")
    local cache_count=0
    local cache_size=0
    
    for cache_dir in "${cache_dirs[@]}"; do
        if [ -d "$cache_dir" ]; then
            local cache_files=$(find "$cache_dir" -name "*.tmp" -o -name "*.part" -o -name "*.download" -type f 2>/dev/null)
            while IFS= read -r file; do
                if [ -f "$file" ]; then
                    cache_size=$((cache_size + $(stat -c%s "$file" 2>/dev/null || echo 0)))
                    ((cache_count++))
                fi
            done <<< "$cache_files"
        fi
    done
    
    details+="⬇️  下载缓存: $cache_count 个, $(echo "scale=2; $cache_size/1024/1024" | bc)MB\n"
    total_size=$((total_size + cache_size))
    total_files=$((total_files + cache_count))
    
    # 服务器备份
    local backup_dir="$MCSERVER_DIR/backups"
    local backup_count=0
    local backup_size=0
    
    if [ -d "$backup_dir" ]; then
        backup_count=$(find "$backup_dir" -name "*.tar.gz" -type f | wc -l)
        backup_size=$(du -sb "$backup_dir" 2>/dev/null | cut -f1)
    fi
    
    details+="💾 服务器备份: $backup_count 个, $(echo "scale=2; $backup_size/1024/1024" | bc)MB\n"
    total_size=$((total_size + backup_size))
    
    # 总结
    details+="\n=== 总计 ===\n"
    details+="文件总数: $total_files 个\n"
    details+="总大小: $(echo "scale=2; $total_size/1024/1024" | bc)MB\n"
    details+="配置目录: $CONFIG_DIR\n"
    
    # 磁盘使用情况
    local disk_info=$(df -h "$CONFIG_DIR" | awk 'NR==2 {print "可用空间: " $4 " / 总空间: " $2 " (" $5 " 已使用)"}')
    details+="磁盘状态: $disk_info\n"
    
    ui_message "缓存文件详情" "$details"
}

# 定期自动清理函数（可在后台运行）
schedule_auto_cleanup() {
    local cleanup_interval=${1:-7}  # 默认7天清理一次
    
    # 检查上次清理时间
    local last_cleanup_file="$CONFIG_DIR/last_cleanup"
    local last_cleanup_time=0
    local current_time=$(date +%s)
    
    if [ -f "$last_cleanup_file" ]; then
        last_cleanup_time=$(cat "$last_cleanup_file")
    fi
    
    local interval_seconds=$((cleanup_interval * 24 * 3600))
    local time_since_last_cleanup=$((current_time - last_cleanup_time))
    
    if [ $time_since_last_cleanup -ge $interval_seconds ]; then
        echo -e "${BLUE}执行定期自动清理...${NC}"
        
        # 执行清理（只清理旧文件）
        cleanup_old_logs_auto
        cleanup_temporary_files_auto
        
        # 记录清理时间
        echo "$current_time" > "$last_cleanup_file"
        echo -e "${GREEN}自动清理完成${NC}"
    fi
}

# 自动清理旧日志（无交互）
cleanup_old_logs_auto() {
    local today=$(date +%Y%m%d)
    local keep_days=7
    
    find "$CONFIG_DIR" -name "*.log.*" -type f 2>/dev/null | while read -r file; do
        if [ -f "$file" ]; then
            local file_date=$(stat -c "%y" "$file" | cut -d' ' -f1 | sed 's/-//g')
            local days_old=$(( (today - file_date) ))
            
            if [ $days_old -gt $keep_days ]; then
                rm -f "$file" 2>/dev/null && echo "自动清理: $file"
            fi
        fi
    done
}

# 自动清理临时文件（无交互）
cleanup_temporary_files_auto() {
    find "$CONFIG_DIR" \( -name "*.tmp" -o -name "*.backup.*" -o -name "*.bak" \) -type f -mtime +1 2>/dev/null | \
    while read -r file; do
        rm -f "$file" 2>/dev/null && echo "自动清理: $file"
    done
}

# 管理器更新功能

# 更新管理器主函数
update_manager() {
    local GITHUB_TOKEN="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"
    local GITHUB_REPO="HEXIkx/mc-server"
    local API_URL="https://api.github.com/repos/$GITHUB_REPO/releases/latest"
    local SCRIPT_NAME="MC-server.sh"

    echo -e "${BLUE}正在检查更新...${NC}"

    local response
    response=$(curl -s --connect-timeout 10 \
        -H "Authorization: Bearer $GITHUB_TOKEN" \
        -H "Accept: application/vnd.github.v3+json" \
        "$API_URL")

    if [ $? -ne 0 ] || [[ -z "$response" ]]; then
        echo -e "${RED}❌ GitHub API 请求失败（检查 Token 或网络）${NC}"
        echo -e "${RED}⚠️ 请确认你的 Token 是否正确！${NC}"
        return 1
    fi

    local latest_tag
    latest_tag=$(echo "$response" | jq -r '.tag_name // empty')
    local download_url
    download_url=$(echo "$response" | jq -r ".assets[] | select(.name == \"$SCRIPT_NAME\") | .browser_download_url // empty")

    # 如果没有找到 asset，尝试从 tag 的 zipball 获取
    if [ -z "$download_url" ]; then
        echo -e "${YELLOW}⚠️ 在 release 中未找到 '$SCRIPT_NAME'，尝试从 tag 获取...${NC}"
        local zipball_url
        zipball_url=$(echo "$response" | jq -r '.zipball_url // empty')
        if [ -n "$zipball_url" ]; then
            # 下载 zipball 并提取脚本
            local tmp_zip="$SCRIPT_PATH.update.zip"
            echo -e "${BLUE}从 tag 下载源码包...${NC}"
            if curl -L -H "Authorization: Bearer $GITHUB_TOKEN" -o "$tmp_zip" --progress-bar "$zipball_url"; then
                # 解压并提取脚本
                local tmp_dir="$SCRIPT_PATH.update.tmp"
                mkdir -p "$tmp_dir"
                if unzip -q "$tmp_zip" -d "$tmp_dir" 2>/dev/null; then
                    # 查找脚本文件
                    local extracted_script
                    extracted_script=$(find "$tmp_dir" -name "$SCRIPT_NAME" -type f 2>/dev/null | head -1)
                    if [ -n "$extracted_script" ]; then
                        cp "$extracted_script" "$tmp_file"
                        rm -rf "$tmp_zip" "$tmp_dir"
                        download_url="from_zipball"
                    else
                        echo -e "${RED}❌ 从 zipball 中未找到 '$SCRIPT_NAME'${NC}"
                        rm -rf "$tmp_zip" "$tmp_dir"
                        return 1
                    fi
                else
                    echo -e "${RED}❌ 解压失败${NC}"
                    rm -rf "$tmp_zip" "$tmp_dir"
                    return 1
                fi
            else
                echo -e "${RED}❌ 下载源码包失败${NC}"
                rm -rf "$tmp_zip" "$tmp_dir"
                return 1
            fi
        else
            echo -e "${RED}❌ 在 release $latest_tag 中未找到文件 '$SCRIPT_NAME'${NC}"
            echo -e "${YELLOW}请确保在 GitHub Release 中上传了该脚本${NC}"
            return 1
        fi
    fi

    if [ -z "$latest_tag" ]; then
        echo -e "${RED}❌ 未找到 release 标签（可能仓库不存在或 Token 无效）${NC}"
        echo -e "${RED}⚠️ 请检查你的 GitHub Token 和仓库设置！${NC}"
        return 1
    fi

    local current_version="${MANAGER_VERSION}"
    local latest_version="${latest_tag#v}" 
    current_version=$(echo "$current_version" | tr -d '[:space:]')
    latest_version=$(echo "$latest_version" | tr -d '[:space:]')

    if [ "$current_version" = "$latest_version" ]; then
        if [ "$NO_GUI" != "true" ]; then
            show_msg "信息" "当前已是最新版本 ($current_version)"
        else
            echo -e "${GREEN}✅ 当前已是最新版本 ($current_version)${NC}"
        fi
        return 0
    fi

    # 比较版本：使用 sort -V 排序，如果 current_version 在前面，说明 current_version < latest_version
    if [ "$(echo -e "$current_version\n$latest_version" | sort -V | head -n1)" = "$current_version" ]; then
        # current_version < latest_version，有新版本
        if [ "$NO_GUI" != "true" ]; then
            show_msg "发现新版本" "发现新版本: $latest_version (当前: $current_version)"
        else
            echo -e "${YELLOW}📢 发现新版本: $latest_version (当前: $current_version)${NC}"
        fi

        # 优先使用用户下载站的链接
        download_url="http://download.hycexit.xyz/MCManagement/$latest_version/MC-server.sh"
    else
        # current_version >= latest_version
        if [ "$NO_GUI" != "true" ]; then
            show_msg "信息" "当前已是最新版本 ($current_version)"
        else
            echo -e "${GREEN}✅ 当前已是最新版本 ($current_version)${NC}"
        fi
        return 0
    fi

    # === 用户确认更新 ===
    if [ "$NO_GUI" != "true" ]; then
        if ! ui_confirm "是否更新到 $latest_tag?"; then
            echo -e "${YELLOW}用户取消更新${NC}"
            return 0
        fi
    else
        read -p "是否更新? (y/N): " -n 1 -r
        echo
        [[ ! $REPLY =~ ^[Yy]$ ]] && return 0
    fi

    # === 关闭图形界面，切换到纯终端模式 ===
    if [ "$NO_GUI" != "true" ]; then
        # 恢复标准输入输出，退出 whiptail 环境
        exec 3<&0  # 恢复 STDIN
        exec 4>&1  # 恢复 STDOUT
        exec 5>&2  # 恢复 STDERR
        clear
        echo -e "${BLUE}正在切换到终端模式进行更新...${NC}"
        sleep 1
    fi

    # === 执行更新===
    local backup_file="$SCRIPT_PATH.bak.$(date +%Y%m%d_%H%M%S)"
    cp "$SCRIPT_PATH" "$backup_file"
    if [ $? -ne 0 ]; then
        echo -e "${RED}❌ 备份失败！中止更新${NC}"
        return 1
    fi
    echo -e "${CYAN}已备份当前脚本至: $backup_file${NC}"

    local tmp_file="$SCRIPT_PATH.update.tmp"

    # 检查是否已经从 zipball 获取了脚本
    if [ "$download_url" != "from_zipball" ]; then
        echo -e "${BLUE}⬇️ 正在下载新版本 ($latest_tag)...${NC}"
        echo -e "${BLUE}下载链接: $download_url${NC}"
        if ! curl -L -o "$tmp_file" --progress-bar "$download_url"; then
            echo -e "${RED}❌ 下载失败！${NC}"
            rm -f "$tmp_file"
            return 1
        fi
    else
        echo -e "${BLUE}⬆️ 正在处理新版本 ($latest_tag)...${NC}"
    fi

    if [ ! -s "$tmp_file" ]; then
        echo -e "${RED}❌ 下载的文件为空！${NC}"
        rm -f "$tmp_file"
        return 1
    fi

    chmod +x "$tmp_file"
    if [ $? -ne 0 ]; then
        echo -e "${RED}❌ 无法设置执行权限！${NC}"
        rm -f "$tmp_file"
        return 1
    fi

    mv "$tmp_file" "$SCRIPT_PATH"
    if [ $? -ne 0 ]; then
        echo -e "${RED}❌ 替换失败！恢复备份...${NC}"
        mv "$backup_file" "$SCRIPT_PATH"
        return 1
    fi

    echo -e "${GREEN}✅ 更新成功！新版本: ${latest_tag#v}${NC}"

    # 自动重启（非调试模式）
    if [ "$DEBUG_MODE" != "true" ]; then
        echo -e "${YELLOW}🔄 正在重启管理器...${NC}"
        sleep 2
        # 重新启动脚本
        exec "$SCRIPT_PATH" "$@"
    else
        echo -e "${MAGENTA}[调试模式] 请手动重启脚本${NC}"
    fi
}

# 直接调用更新（用于 --update-manager 参数）
update_manager_direct() {
    echo "=== Minecraft 服务器管理器更新工具 ==="
    update_manager
}

# 显示系统信息

show_system_info() {
    # 获取系统信息
    local os_info=""
    os_info=$(grep PRETTY_NAME /etc/os-release | cut -d= -f2 | tr -d '"')
    
    local kernel=$(uname -r)
    
    # 获取 CPU 信息
    local cpu_info=""
    if command -v lscpu >/dev/null 2>&1; then
        cpu_info=$(lscpu 2>/dev/null | grep "Model name" | cut -d: -f2 | sed 's/^ *//' | head -1)
    fi
    
    if [ -z "$cpu_info" ] && [ -f "/proc/cpuinfo" ]; then
        cpu_info=$(grep -m 1 "model name" /proc/cpuinfo 2>/dev/null | cut -d: -f2 | sed 's/^ *//')
        if [ -z "$cpu_info" ]; then
            cpu_info=$(grep -m 1 "Hardware" /proc/cpuinfo 2>/dev/null | cut -d: -f2 | sed 's/^ *//')
        fi
    fi
    
    if [ -z "$cpu_info" ]; then
        cpu_info="未知 ($ARCH 架构)"
    fi
    
    # 获取内存信息 - 使用更精确的单位转换
    local mem_info=""
    if command -v free >/dev/null 2>&1; then
        # 使用 -b 选项以字节为单位，然后手动转换
        local mem_total_bytes=$(free -b | grep Mem | awk '{print $2}')
        local mem_used_bytes=$(free -b | grep Mem | awk '{print $3}')
        local mem_available_bytes=$(free -b | grep Mem | awk '{print $7}')
        
        # 转换为GB/MB，保留一位小数
        local mem_total_mb=$((mem_total_bytes / 1024 / 1024))
        local mem_used_mb=$((mem_used_bytes / 1024 / 1024))
        local mem_available_mb=$((mem_available_bytes / 1024 / 1024))
        
        if [ $mem_total_mb -ge 1024 ]; then
            local mem_total_gb=$(echo "$mem_total_mb / 1024" | bc -l | xargs printf "%.1f")
            local mem_used_gb=$(echo "$mem_used_mb / 1024" | bc -l | xargs printf "%.1f")
            local mem_available_gb=$(echo "$mem_available_mb / 1024" | bc -l | xargs printf "%.1f")
            mem_info="内存: ${mem_used_gb}GB 已用 / ${mem_total_gb}GB 总共 (${mem_available_gb}GB 可用)"
        else
            mem_info="内存: ${mem_used_mb}MB 已用 / ${mem_total_mb}MB 总共 (${mem_available_mb}MB 可用)"
        fi
    fi
    
    if [ -z "$mem_info" ] && [ -f "/proc/meminfo" ]; then
        local mem_total_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}')
        local mem_available_kb=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
        
        if [ -n "$mem_total_kb" ] && [ -n "$mem_available_kb" ]; then
            local mem_total_mb=$((mem_total_kb / 1024))
            local mem_available_mb=$((mem_available_kb / 1024))
            local mem_used_mb=$((mem_total_mb - (mem_total_mb - mem_available_mb)))
            
            if [ $mem_total_mb -gt 1000 ]; then
                local mem_total_gb=$(echo "$mem_total_mb / 1024" | bc -l | xargs printf "%.1f")
                local mem_available_gb=$(echo "$mem_available_mb / 1024" | bc -l | xargs printf "%.1f")
                local mem_used_gb=$(echo "($mem_total_mb - $mem_available_mb) / 1024" | bc -l | xargs printf "%.1f")
                mem_info="内存: ${mem_used_gb}GB 已用 / ${mem_total_gb}GB 总共 (${mem_available_gb}GB 可用)"
            else
                mem_info="内存: ${mem_used_mb}MB 已用 / ${mem_total_mb}MB 总共 (${mem_available_mb}MB 可用)"
            fi
        fi
    fi
    
    if [ -z "$mem_info" ]; then
        mem_info="内存: 无法获取内存信息"
    fi
    
    # 获取存储信息 - 修正单位显示
    local disk_info=""
    if command -v df >/dev/null 2>&1; then
        # 使用 -B 选项指定单位
        local disk_total=$(df -B1 / | awk 'NR==2 {print $2}')
        local disk_used=$(df -B1 / | awk 'NR==2 {print $3}')
        local disk_available=$(df -B1 / | awk 'NR==2 {print $4}')
        local disk_percentage=$(df -B1 / | awk 'NR==2 {print $5}')
        
        # 转换为GB/MB单位
        local disk_total_gb=$(echo "$disk_total / 1024 / 1024 / 1024" | bc -l | xargs printf "%.1f")
        local disk_used_gb=$(echo "$disk_used / 1024 / 1024 / 1024" | bc -l | xargs printf "%.1f")
        local disk_available_gb=$(echo "$disk_available / 1024 / 1024 / 1024" | bc -l | xargs printf "%.1f")
        
        disk_info="存储: ${disk_available_gb}GB 可用 / ${disk_total_gb}GB 总共 (${disk_percentage} 已使用)"
    else
        disk_info="存储: 无法获取存储信息"
    fi
    
    # 获取电池信息（仅限移动设备）
    local battery_info=""
    if [ -f "/sys/class/power_supply/battery/capacity" ]; then
        battery_capacity=$(cat /sys/class/power_supply/battery/capacity 2>/dev/null)
        battery_status=$(cat /sys/class/power_supply/battery/status 2>/dev/null || echo "未知")
        if [ -n "$battery_capacity" ]; then
            battery_info="电池: $battery_capacity% ($battery_status)"
        fi
    fi
    
    # 构建信息字符串
    local info="=== 系统信息 ===\n\n"
    info+="🖥️  操作系统: $os_info\n"
    info+="📦 内核版本: $kernel\n"
    info+="🏗️  系统架构: $ARCH\n"
    info+="⚡ CPU: $cpu_info\n"
    info+="💾 $mem_info\n"
    info+="📁 $disk_info\n"
    
    if [ -n "$battery_info" ]; then
        info+="🔋 $battery_info\n"
    fi
    
    info+="\n"
    info+="=== 管理器信息 ===\n\n"
    info+="📋 版本: $MANAGER_VERSION\n"
    info+="📊 服务器数量: $(jq -r '.servers | length' "$CONFIG_FILE" 2>/dev/null || echo 0)\n"
    info+="☕ JDK数量: $(jq -r '.jdks | length' "$CONFIG_FILE" 2>/dev/null || echo 0)\n"
    info+="📂 服务器目录: $MCSERVER_DIR\n"
    info+="📂 JDK目录: $MCJDK_DIR\n"
    info+="📂 配置目录: $CONFIG_DIR\n"
    
    # 显示信息
    ui_message "系统信息" "$info"
}

# 主程序入口和初始化

# 主程序入口
main() {
    # 解析命令行参数
    parse_arguments "$@"

    # 初始化检查
    init_checks

    # 调试模式
    if [ "$DEBUG_MODE" = "true" ]; then
        set -x
    fi

    # 无GUI模式处理（CLI 模式，不依赖 whiptail）
    if [ "$NO_GUI" = "true" ]; then
        handle_no_gui_mode
        exit 0
    fi

    # GUI 模式：强制检查 whiptail 可用性
    check_whiptail

    # 跳过欢迎界面
    if [ "$SKIP_WELCOME" != "true" ]; then
        show_welcome
    fi

    # 处理目标菜单或函数
    if [ -n "$TARGET_MENU" ] || [ -n "$TARGET_FUNCTION" ] || [ -n "$GOTO_MENU" ]; then
        handle_target_execution
    else
        # 正常进入主菜单（GUI 模式）
        main_menu
    fi
}

# 脚本执行入口

# 保存原始终端设置（非交互式环境下跳过）
if [ -t 0 ]; then
    original_term=$(stty -g 2>/dev/null || echo "")
else
    original_term=""
fi

# 设置退出清理（保持原样）
trap 'stty "$original_term" 2>/dev/null; cleanup_on_exit' EXIT
trap 'error_handler $LINENO' ERR

# 全局变量初始化
TARGET_MENU=""
TARGET_FUNCTION=""
GOTO_MENU=""
SERVER_NAME=""
JDK_VERSION=""
SKIP_WELCOME="false"
SKIP_MAIN_MENU="false"
DEBUG_MODE="false"
NO_GUI="false"
cli_mode="false"
_download_in_progress="false"  # 标记是否有下载正在进行
_download_cancelled="false"    # 标记下载是否被用户取消

# 主执行入口
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
    # 检查参数中是否包含 CLI 模式参数
    cli_mode=false
    for arg in "$@"; do
        case "$arg" in
            --no-gui|--no-gui=*|\
            --list-menus|--list-functions|--list-servers|--list-jdks|\
            --status|--help|--version|\
            --start-server|--backup-server|--install-jdk|--update-manager|\
            -t|--target-menu|-tf|--target-function|\
            -n|--name|-j|--jdk|-d|--debug)
                cli_mode=true
                break
                ;;
        esac
    done

    if [ -t 0 ] || [ "$cli_mode" = true ]; then
        main "$@"
    else
        echo "请在交互式终端中运行此脚本"
        exit 1
    fi
fi





