#!/bin/bash

# =====================================================
#   Minecraft Java 方便式一键脚本
#   版本: 1.0.0
#   作者: hycexit
# =====================================================

# =====================================================
#   命令行参数解析
# =====================================================
IN_EDIT_MODE="false"
IN_LOG_VIEW_MODE="false"
CURRENT_SERVER=""
CURRENT_MENU=""

# 解析命令行参数
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
                shift 2
                ;;
            -tf|--target-function)
                target_function="$2"
                skip_main_menu=true
                shift 2
                ;;
            -gof|--goto-menu)
                goto_menu="$2"
                skip_main_menu=false  # 不跳过主菜单
                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)
                list_available_menus
                exit 0
                ;;
            --list-functions)
                list_available_functions
                exit 0
                ;;
            --list-servers)
                list_servers
                exit 0
                ;;
            --list-jdks)
                list_jdks
                exit 0
                ;;
            --status)
                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
                ;;
            *)
                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        - 系统设置
  show_faq               - 常见问题
EOF
}

# 列出所有可用函数
list_available_functions() {
    cat << EOF
可用函数:
服务器管理:
  create_server                 - 创建新服务器
  manage_existing_servers       - 管理现有服务器
  start_server                 - 启动服务器
  configure_server             - 配置服务器
  manage_server_files          - 文件与配置
  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               - 更新管理器
  reset_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
}

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
}
# =====================================================
#   直接执行功能（无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"
}

# 直接安装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
}

# 检查服务器是否存在
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
}

# =====================================================
#   获取脚本绝对路径
# =====================================================

# 获取脚本的绝对路径
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'
NC='\033[0m' # 无颜色

# 路径配置
BASE_DIR="$HOME"
MCSERVER_DIR="$BASE_DIR/MCServers"
MCJDK_DIR="$BASE_DIR/MC_JDK"
CONFIG_DIR="$BASE_DIR/.mcmanager"
PLUGIN_DIR="$CONFIG_DIR/plugins"
MOD_DIR="$CONFIG_DIR/mods"
LOG_DIR="$CONFIG_DIR/logs"
HP_DIR="$CONFIG_DIR/hppro"
HP_LOG_FILE="$HP_DIR/hp-client.log"

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

# 管理器版本
MANAGER_VERSION="1.0.0"

# 初始化配置文件
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": ""
    }
}
EOF
    fi
}

# 加载配置
load_config() {
    if [ -f "$CONFIG_FILE" ]; then
        DEFAULT_JAVA_VERSION=$(jq -r '.manager.default_java_version' "$CONFIG_FILE")
        HP_DEVICE_ID=$(jq -r '.hppro.device_id' "$CONFIG_FILE")
        HP_DOWNLOADED=$(jq -r '.hppro.downloaded' "$CONFIG_FILE")
    else
        DEFAULT_JAVA_VERSION="暂未设置"
        HP_DEVICE_ID=""
        HP_DOWNLOADED="false"
    fi
}

# 保存配置
save_config() {
    local temp_file="$CONFIG_FILE.tmp"
    
    jq --arg default_java "$DEFAULT_JAVA_VERSION" \
       --arg device_id "$HP_DEVICE_ID" \
       --argjson downloaded "$HP_DOWNLOADED" \
       '.manager.default_java_version = $default_java |
        .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
}

# 验证安装结果
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" "系统设置" \
            "5" "常见问题" \
            "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 ;;
            5) show_faq ;;
            0 | "") exit 0 ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 初始化检查
init_checks() {
    # 检查依赖
    check_dependencies
    
    # 检查目录
    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=$?
    
    # 如果是编辑模式或日志查看模式，特殊处理
    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}"
        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
    
    # 记录错误日志
    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"
    status_info+="默认Java: $DEFAULT_JAVA_VERSION\n"
    
    echo -e "$status_info"
}

# 初始化日志
init_log() {
    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"
    safe_whiptail --title "$title" --msgbox "$msg" 10 50
}

# 获取终端宽度并计算进度条宽度
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
    
    # 计算进度条宽度（终端宽度减去其他信息的固定宽度）
    local bar_width=$((term_width - 40))
    
    # 设置最小和最大宽度限制
    if [ $bar_width -lt 20 ]; then
        bar_width=20
    elif [ $bar_width -gt 60 ]; then
        bar_width=60
    fi
    
    echo $bar_width
}

# 显示进度条
show_progress() {
    local title="$1"
    local msg="$2"
    local percent="$3"
    local speed="$4"
    
    # 进度条宽度
    local bar_width=$(get_progress_bar_width)
    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 %s %3d%%" "$title" "$msg" "$bar" "$percent"
    
    # 添加速度信息
    if [ -n "$speed" ]; then
        printf " | %s/s${NC}" "$speed"
    else
        printf "${NC}"
    fi
    
    # 完成时显示完整消息
    if [ "$percent" = "100" ]; then
        printf "\n${GREEN}%s: 完成!${NC}\n" "$title"
    fi
}

# 实时下载进度显示
download_with_progress() {
    local url="$1"
    local output_file="$2"
    local title="$3"
    local message="$4"
    
    local bar_width=$(get_progress_bar_width)
    
    # 使用curl的进度显示
    if command -v curl >/dev/null 2>&1; then
        curl -L -o "$output_file" --progress-bar "$url" 2>&1 | \
        stdbuf -oL tr '\r' '\n' | \
        while IFS= read -r line; do
            if [[ $line =~ ([0-9]+\.?[0-9]*)% ]]; then
                local percent=$(printf "%.0f" "${BASH_REMATCH[1]}")
                local speed=$(echo "$line" | grep -o '[0-9]*\.[0-9]* [A-Z]B/s' | head -1)
                update_progress_bar_with_width "$title" "$message" "$percent" "$bar_width" "$speed"
            fi
        done
        
        # 检查下载是否成功
        if [ $? -eq 0 ] && [ -f "$output_file" ]; then
            update_progress_bar_with_width "$title" "$message" "100" "$bar_width"
            echo ""
            return 0
        else
            echo -e "${RED}下载失败!${NC}"
            return 1
        fi
    else
        # 如果curl不可用，使用wget
        wget -O "$output_file" "$url" 2>&1 | \
        while IFS= read -r line; do
            if [[ $line =~ ([0-9]+)% ]]; then
                local percent="${BASH_REMATCH[1]}"
                update_progress_bar_with_width "$title" "$message" "$percent" "$bar_width"
            fi
        done
        
        if [ $? -eq 0 ] && [ -f "$output_file" ]; then
            update_progress_bar_with_width "$title" "$message" "100" "$bar_width"
            echo ""
            return 0
        else
            echo -e "${RED}下载失败!${NC}"
            return 1
        fi
    fi
}

# 更新进度条显示
update_progress_bar_with_width() {
    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 %s %3d%%" "$title" "$msg" "$bar" "$percent"
    
    # 添加速度信息
    if [ -n "$speed" ]; then
        printf " | %s/s${NC}" "$speed"
    else
        printf "${NC}"
    fi
}

# 处理无GUI模式
handle_no_gui_mode() {
    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
            echo "错误: 函数 '$TARGET_FUNCTION' 不存在"
            exit 1
        fi
    elif [ -n "$TARGET_MENU" ]; then
        echo "错误: 无GUI模式下不支持直接跳转到菜单"
        exit 1
    else
        echo "错误: 无GUI模式下需要指定要执行的函数"
        show_help
        exit 1
    fi
}

# 处理目标执行
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"
    
    case "$target_menu" in
        "main_menu")
            main_menu
            ;;
        "server_management")
            server_management
            ;;
        "jdk_management")
            jdk_management
            ;;
        "hp_management")
            hp_management
            ;;
        "system_settings")
            system_settings
            ;;
        "show_faq")
            show_faq
            ;;
        *)
            show_msg "错误" "未知菜单: $target_menu"
            main_menu
            ;;
    esac
}

# 跳转到目标菜单（保持主循环）
goto_target_menu() {
    local target_menu="$1"
    
    # 设置环境变量以便错误处理知道当前上下文
    export CURRENT_MENU="$target_menu"
    
    case "$target_menu" in
        "main_menu")
            main_menu
            ;;
        "server_management")
            server_management
            ;;
        "jdk_management")
            jdk_management
            ;;
        "hp_management")
            hp_management
            ;;
        "system_settings")
            system_settings
            ;;
        "show_faq")
            show_faq
            ;;
        "hp_log_menu")
            hp_log_menu
            ;;
        *)
            show_msg "错误" "未知菜单: $target_menu"
            main_menu
            ;;
    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
        restore_file_descriptors
        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() {
    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
}

# 创建新服务器
create_server() {
    local server_name server_dir server_type mc_version
    local server_type_choice
    
    # 外层循环：服务器名称输入
    while true; do
        # 获取服务器名称
        server_name=$(safe_whiptail --inputbox "请输入服务器名称（只能包含字母、数字、下划线）：" 8 40 3>&1 1>&2 2>&3)
        if [ $? -ne 0 ]; then
            # 用户取消输入名称，直接返回服务器管理菜单
            return
        fi
        
        if [ -z "$server_name" ]; then
            show_msg "错误" "服务器名称不能为空"
            continue
        fi
        
        # 验证服务器名称格式
        if ! [[ "$server_name" =~ ^[a-zA-Z0-9_]+$ ]]; then
            show_msg "错误" "服务器名称只能包含字母、数字和下划线"
            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"
        
        # 内层循环：服务器类型和版本选择
        while true; do
            # 选择服务器类型
            server_type_choice=$(safe_whiptail --menu "选择服务器类型：" 15 50 6 \
                "1" "Vanilla (原版)" \
                "2" "Paper (高性能)" \
                "3" "Spigot (插件服)" \
                "4" "Forge (模组服)" \
                "5" "Fabric (轻量模组)" \
                "6" "Folia (多线程高性能)" \
                3>&1 1>&2 2>&3)
            
            if [ $? -ne 0 ]; then
                rm -rf "$server_dir"
                return
            fi
            
            case $server_type_choice in
                1) server_type="vanilla" ;;
                2) server_type="paper" ;;
                3) server_type="spigot" ;;
                4) server_type="forge" ;;
                5) server_type="fabric" ;;
                6) server_type="folia" ;;
                *) 
                    show_msg "错误" "无效的服务器类型选择"
                    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")
                            if [ "$version" = "1.20.6" ] || [ "$version" = "1.21.1" ]; then
                                recommended="(推荐)"
                            fi
                            ;;
                        "paper"|"spigot")
                            if [ "$version" = "1.20.6" ] || [ "$version" = "1.21.1" ]; then
                                recommended="(推荐)"
                            fi
                            ;;
                        "forge")
                            if [ "$version" = "1.20.1" ] || [ "$version" = "1.19.2" ]; then
                                recommended="(模组丰富)"
                            fi
                            ;;
                        "fabric")
                            if [ "$version" = "1.20.1" ] || [ "$version" = "1.21.1" ]; then
                                recommended="(推荐)"
                            fi
                            ;;
                        "folia")
                            if [ "$version" = "1.21.8" ] || [ "$version" = "1.20.6" ]; then
                                recommended="(多线程优化)"
                            elif [ "$version" = "1.19.4" ]; 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"; then
                    show_msg "错误" "版本号格式不正确，应为: X.X.X 或 X.X"
                    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"

            # 添加 Folia 特定警告
            if [ "$server_type" = "folia" ]; then
                summary+="\n⚠️  Folia 多线程服务器注意事项:\n"
                summary+="• 需要 JDK 17+\n"
                summary+="• 部分插件可能不兼容\n"
                summary+="• 建议 4GB+ 内存\n"
                summary+="• 多线程优化，适合大型服务器\n"
            fi
            
            # 确认创建
            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"; then
                # 自动选择适合的JDK版本
                local recommended_jdk=$(get_recommended_jdk_for_version "$mc_version")
                
                # 创建启动脚本
                if create_start_script "$server_dir" "$server_type" "$mc_version" "$recommended_jdk"; then
                    # 添加到服务器配置
                    add_server_to_config "$server_name" "$server_type" "$mc_version"
                    
                    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 2
        done
    done
}

# 获取服务器类型支持的版本列表
get_supported_versions() {
    local server_type="$1"
    local -n versions_ref="$2"  # 使用nameref来修改数组
    
    case "$server_type" in
        "vanilla")
            # Vanilla 官方原版
            versions_ref=(
                "1.21.10" "1.21.9" "1.21.8" "1.21.7" "1.21.6" "1.21.5" "1.21.4" "1.21.3" "1.21.2" "1.21.1" "1.21" 
                "1.20.6" "1.20.5" "1.20.4" "1.20.3" "1.20.2" "1.20.1" "1.20"
                "1.19.4" "1.19.3" "1.19.2" "1.19.1" "1.19"
                "1.18.2" "1.18.1" "1.18"
                "1.17.1" "1.17"
                "1.16.5" "1.16.4" "1.16.3" "1.16.2" "1.16.1" "1.16"
                "1.15.2" "1.15.1" "1.15"
                "1.14.4" "1.14.3" "1.14.2" "1.14.1" "1.14"
                "1.13.2" "1.13.1" "1.13" 
                "1.12.2" "1.12.1" "1.12"
                "1.11.2" "1.11.1" "1.11"
                "1.10.2" "1.10.1" "1.10"
                "1.9.4" "1.9.3" "1.9.2" "1.9.1" "1.9"
                "1.8.9" "1.8.8" "1.8.7" "1.8.6" "1.8.5" "1.8.4" "1.8.3" "1.8.2" "1.8.1" "1.8" 
                "1.7.10" "1.7.9" "1.7.8" "1.7.7" "1.7.6" "1.7.5" "1.7.4" "1.7.3" "1.7.2" "1.7.1" "1.7"
                "1.6.4" "1.6.3" "1.6.2" "1.6.1" "1.6"
                "1.5.2" "1.5.1" "1.5"
                "1.4.7" "1.4.6" "1.4.5" "1.4.4" "1.4.3" "1.4.2" "1.4.1" "1.4"
                "1.3.2" "1.3.1" "1.3"
                "1.2.5" "1.2.4" "1.2.3" "1.2.2" "1.2.1" "1.2" 
                "1.1" "1.0" 
                "custom"
            )
            ;;
        "paper")
            # Paper
            versions_ref=(
                "1.21.10" "1.21.9" "1.21.8" "1.21.7" "1.21.6" "1.21.5" "1.21.4" "1.21.3" "1.21.2" "1.21.1" "1.21"
                "1.20.6" "1.20.5" "1.20.4" "1.20.3" "1.20.2" "1.20.1" "1.20"
                "1.19.4" "1.19.3" "1.19.2" "1.19.1" "1.19"
                "1.18.2" "1.18.1" "1.18"
                "1.17.1" "1.17"
                "1.16.5" "1.16.4" "1.16.3" "1.16.2" "1.16.1"
                "1.15.2" "1.15.1" "1.15"
                "1.14.4" "1.14.3" "1.14.2" "1.14.1" "1.14"
                "1.13.2" "1.13.1" "1.13"
                "1.12.2" "1.12.1" "1.12"
                "1.11.2"
                "1.10.2"
                "1.9.4"
                "1.8.8"
                "1.7.10"
                "custom"
            )
            ;;
        "folia")
            # folia
            versions_ref=(
                "1.21.8" "1.21.6" "1.21.5" "1.21.4"
                "1.20.6" "1.20.4" "1.20.2" "1.20.1"
                "1.19.4"
                "custom"
            )
            ;;
        "spigot")
            # Spigot
            versions_ref=(
                "1.21.10" "1.21.8" "1.21.5" "1.21.4" "1.21.3" "1.21.1"
                "1.20.6" "1.20.5" "1.20.4" "1.20.3" "1.20.2" "1.20.1" "1.20"
                "1.19.4" "1.19.3" "1.19.2" "1.19.1" "1.19"
                "1.18.2" "1.18.1" "1.18"
                "1.16.5" "1.16.4" "1.16.3" "1.16.2" "1.16.1"
                "1.15.2" "1.15.1" "1.15"
                "1.14.4" "1.14.3" "1.14.2" "1.14.1" "1.14"
                "1.13.2" "1.13.1" "1.13"
                "1.12.2" "1.12.1" "1.12"
                "1.11" "1.11.2"
                "1.10.2"
                "1.9" "1.9.2" "1.9.4"
                "1.8" "1.8.3" "1.8.8"
                "custom"
            )
            ;;
        "forge")
            # Forge
            versions_ref=(
                "1.21.10" "1.21.9" "1.21.8" "1.21.7" "1.21.6" "1.21.5" "1.21.4" "1.21.3" "1.21.1" "1.21" 
                "1.20.6" "1.20.4" "1.20.3" "1.20.2" "1.20.1" "1.20"
                "1.19.4" "1.19.3" "1.19.2" "1.19.1" "1.19"
                "1.18.2" "1.18.1" "1.18"
                "1.17.1"
                "1.16.5" "1.16.4" "1.16.3" "1.16.2" "1.16.1"
                "1.15.2" "1.15.1" "1.15"
                "1.14.4" "1.14.3" "1.14.2"
                "1.13.2"
                "1.12.2" "1.12.1" "1.12"
                "1.11.2" "1.11"
                "1.10.2" "1.10"
                "1.9.4" "1.9"
                "1.8.9" "1.8.8" "1.8" 
                "1.7.10" "1.7.2" 
                "1.6.4" "1.6.3" "1.6.2" "1.6.1" 
                "1.5.2"
                "custom"
            )
            ;;
        "fabric")
            # Fabric
            versions_ref=(
                "1.21.10" "1.21.9" "1.21.8" "1.21.7" "1.21.6" "1.21.5" "1.21.4" "1.21.3" "1.21.2" "1.21.1" "1.21" 
                "1.20.6" "1.20.5" "1.20.4" "1.20.3" "1.20.2" "1.20.1" "1.20"
                "1.19.4" "1.19.3" "1.19.2" "1.19.1" "1.19"
                "1.18.2" "1.18.1" "1.18"
                "1.17.1" "1.17"
                "1.16.5" "1.16.4" "1.16.3" "1.16.2" "1.16.1" "1.16"
                "1.15.2" "1.15.1" "1.15"
                "1.14.4" "1.14.3" "1.14.2" "1.14.1" "1.14"
                "custom"
            )
            ;;
        *)
            versions_ref=("custom")
            ;;
    esac
}

# 验证版本格式
validate_version_format() {
    local version="$1"
    
    # 基本格式验证: X.X 或 X.X.X
    if ! [[ "$version" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then
        return 1
    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
    
    if [ "$minor" -lt 0 ] || [ "$minor" -gt 21 ]; then
        return 1
    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")
            # 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 -e "${YELLOW}警告: Folia对1.19以下版本支持有限${NC}"
                return 1
            fi
            
            # 推荐使用1.20+以获得完整功能
            if [ "$major" -eq 1 ] && [ "$minor" -lt 20 ]; then
                echo -e "${YELLOW}注意: 建议使用1.20+版本以获得最佳多线程性能${NC}"
                return 1
            fi
            ;;
        "spigot")
            # Spigot 支持 1.4.7+
            if [ "$major" -eq 1 ] && [ "$minor" -lt 4 ]; then
                echo "错误: Spigot 不支持 1.4 以下版本"
                return 1
            fi
            ;;
        "forge")
            # Forge 支持 1.6.4+
            if [ "$major" -eq 1 ] && [ "$minor" -lt 6 ]; then
                echo "错误: Forge 不支持 1.6 以下版本"
                return 1
            fi
            ;;
        "fabric")
            # Fabric 支持 1.14+
            if [ "$major" -eq 1 ] && [ "$minor" -lt 14 ]; then
                echo "错误: Fabric 不支持 1.14 以下版本"
                return 1
            fi
            ;;
    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
            ;;
        "folia")
            info="🚀🚀 Folia 多线程高性能，适合大型服务器"
            if [ "$major" -eq 1 ] && [ "$minor" -ge 20 ]; then
                info+="\n✅ 完美支持多线程区域系统"
            elif [ "$major" -eq 1 ] && [ "$minor" -eq 19 ]; then
                info+="\n⚠️  早期版本，部分功能可能受限"
            fi
            ;;
        "spigot")
            info="🔌 Spigot 插件丰富，社区支持完善"
            if [ "$major" -eq 1 ] && [ "$minor" -lt 12 ]; then
                info="🔌 经典版本，插件生态成熟"
            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
            ;;
    esac
    
    # 添加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 temp_file="$CONFIG_FILE.tmp"
    
    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"
}

# 下载服务器核心
download_server_core() {
    local server_type=$1
    local mc_version=$2
    local server_dir=$3
    
    # 隐藏图形界面
    clear
    echo -e "${BLUE}正在准备下载服务器核心...${NC}"
    
    # 检查版本兼容性
    if ! check_version_compatibility "$server_type" "$mc_version"; then
        echo -e "${RED}版本兼容性检查失败${NC}"
        return 1
    fi
    
    # 根据服务器类型选择下载方法
    case $server_type in
        "vanilla")
            download_vanilla_server "$mc_version" "$server_dir"
            ;;
        "paper")
            download_paper_server "$mc_version" "$server_dir"
            ;;
        "folia")
            download_folia_server "$mc_version" "$server_dir"
            ;;
        "spigot")
            download_spigot_server "$mc_version" "$server_dir"
            ;;
        "forge")
            download_forge_server "$mc_version" "$server_dir"
            ;;
        "fabric")
            download_fabric_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")
            if [ "$major" -eq 1 ] && [ "$minor" -lt 8 ]; then
                echo -e "${RED}错误: Paper 不支持 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")
            if [ "$major" -eq 1 ] && [ "$minor" -lt 6 ]; then
                echo -e "${RED}错误: Forge 不支持 1.6 以下版本${NC}"
                return 1
            fi
            ;;
        "fabric")
            if [ "$major" -eq 1 ] && [ "$minor" -lt 14 ]; then
                echo -e "${RED}错误: Fabric 不支持 1.14 以下版本${NC}"
                return 1
            fi
            ;;
    esac
    
    echo -e "${GREEN}版本兼容性检查通过${NC}"
    return 0
}

# 验证下载的核心文件
validate_downloaded_core() {
    local server_dir="$1"
    local server_type="$2"
    
    local core_file="$server_dir/server.jar"
    
    if [ ! -f "$core_file" ]; then
        echo -e "${RED}错误: 未找到服务器核心文件${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
    
    # 检查文件类型
    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
    
    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
}

# 下载Paper服务器
download_paper_server() {
    local mc_version=$1
    local server_dir=$2
    
    echo -e "${BLUE}正在下载 Paper $mc_version ...${NC}"
    
    # PaperMC API v2
    local paper_api="https://api.papermc.io/v2/projects/paper"
    
    # 获取构建版本
    echo -e "${YELLOW}正在获取 PaperMC 构建信息...${NC}"
    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

    # 调试信息：显示API响应
    if [ "$DEBUG_MODE" = "true" ]; then
        echo "API响应: $builds_info"
    fi
    
    # 获取最新构建版本
    local latest_build=$(echo "$builds_info" | jq -r '.builds[-1].build // .builds[-1] | tonumber? // .builds[-1]' 2>/dev/null)
    if [ -z "$latest_build" ] || [ "$latest_build" = "null" ]; then
        echo -e "${RED}错误: 无法找到 Paper $mc_version 的构建${NC}"
        return 1
    fi
    
    # 构建下载URL
    local download_url="$paper_api/versions/$mc_version/builds/$latest_build/downloads/paper-$mc_version-$latest_build.jar"
    
    echo -e "${BLUE}下载URL: $download_url${NC}"
    
    # 验证URL是否有效
    if ! validate_download_url "$download_url"; then
        echo -e "${RED}错误: 下载URL无效${NC}"
        echo -e "${YELLOW}尝试备用下载方案...${NC}"
        
        # 备用方案1: 使用直接下载链接
        local alt_url1="https://api.papermc.io/v2/projects/paper/versions/$mc_version/builds/$latest_build/downloads/paper-$mc_version-$latest_build.jar"
        
        # 备用方案2: 使用CDN链接
        local alt_url2="https://download.papermc.io/v2/projects/paper/versions/$mc_version/builds/$latest_build/downloads/paper-$mc_version-$latest_build.jar"
        
        for alt_url in "$alt_url1" "$alt_url2"; do
            echo -e "${BLUE}尝试备用URL: $alt_url${NC}"
            if validate_download_url "$alt_url"; then
                download_url="$alt_url"
                echo -e "${GREEN}备用URL验证成功${NC}"
                break
            fi
        done
    fi
    
    # 下载服务器JAR
    if download_with_progress "$download_url" "$server_dir/server.jar" "正在下载" "Paper服务器..."; then
        # 验证下载的文件
        if validate_downloaded_core "$server_dir" "paper"; then
            echo -e "${GREEN}Paper 服务器下载成功${NC}"
            return 0
        else
            echo -e "${RED}下载的文件验证失败${NC}"
            return 1
        fi
    else
        echo -e "${RED}Paper 服务器下载失败${NC}"
        return 1
    fi
}

# 下载Folia服务器
download_folia_server() {
    local mc_version=$1
    local server_dir=$2
    
    echo -e "${BLUE}正在下载 Folia $mc_version ...${NC}"
    
    # PaperMC API v2
    local folia_api="https://api.papermc.io/v2/projects/folia"
    
    # 获取构建版本
    echo -e "${YELLOW}正在获取 Folia 构建信息...${NC}"
    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

    # 调试信息
    if [ "$DEBUG_MODE" = "true" ]; then
        echo "API响应: $builds_info"
    fi
    
    # 获取最新构建版本
    local latest_build=$(echo "$builds_info" | jq -r '.builds[-1].build // .builds[-1] | tonumber? // .builds[-1]' 2>/dev/null)
    if [ -z "$latest_build" ] || [ "$latest_build" = "null" ]; then
        echo -e "${RED}错误: 无法找到 Folia $mc_version 的构建${NC}"
        return 1
    fi
    
    # 构建下载URL
    local download_url="$folia_api/versions/$mc_version/builds/$latest_build/downloads/folia-$mc_version-$latest_build.jar"
    
    echo -e "${BLUE}下载URL: $download_url${NC}"
    
    # 验证URL是否有效
    if ! validate_download_url "$download_url"; then
        echo -e "${RED}错误: 下载URL无效${NC}"
        echo -e "${YELLOW}尝试备用下载方案...${NC}"
        
        # 备用方案1: 使用直接下载链接
        local alt_url1="https://api.papermc.io/v2/projects/folia/versions/$mc_version/builds/$latest_build/downloads/folia-$mc_version-$latest_build.jar"
        
        # 备用方案2: 使用CDN链接
        local alt_url2="https://download.papermc.io/v2/projects/folia/versions/$mc_version/builds/$latest_build/downloads/folia-$mc_version-$latest_build.jar"
        
        for alt_url in "$alt_url1" "$alt_url2"; do
            echo -e "${BLUE}尝试备用URL: $alt_url${NC}"
            if validate_download_url "$alt_url"; then
                download_url="$alt_url"
                echo -e "${GREEN}备用URL验证成功${NC}"
                break
            fi
        done
    fi
    
    # 下载服务器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
}

# 下载Spigot服务器
download_spigot_server() {
    local mc_version=$1
    local server_dir=$2
    
    echo -e "${BLUE}正在下载 Spigot $mc_version ...${NC}"
    
    # Spigot 下载URL
    local spigot_url="https://cdn.getbukkit.org/spigot/spigot-$mc_version.jar"
    
    echo -e "${YELLOW}注意: Spigot 可能需要较长时间下载...${NC}"
    
    if download_with_progress "$spigot_url" "$server_dir/server.jar" "正在下载" "Spigot服务器..."; then
        return 0
    else
        echo -e "${RED}Spigot 服务器下载失败，尝试备用方案...${NC}"
        
        # 备用方案
        local alt_urls=(
            "http://download.hycexit.xyz/spigot/spigot-$mc_version.jar"
        )
        
        for alt_url in "${alt_urls[@]}"; do
            echo -e "${BLUE}尝试备用URL: $alt_url${NC}"
            if download_with_progress "$alt_url" "$server_dir/server.jar" "正在下载" "Spigot服务器(备用)..."; then
                echo -e "${GREEN}备用方案下载成功${NC}"
                return 0
            fi
        done
        
        echo -e "${RED}所有 Spigot 下载源都失败${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
}

# 服务器操作菜单
server_operations_menu() {
    local server_name="$1"
    
    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
    
    # 选择服务器
    selected=$(safe_whiptail --menu "选择要管理的服务器：" 20 60 10 "${servers[@]}" 3>&1 1>&2 2>&3)
    [ $? -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}"
    
    # 获取合适的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
        echo -e "${YELLOW}警告: Java路径 $java_path 不可用，尝试使用系统Java${NC}"
        if command -v java >/dev/null 2>&1; then
            java_path="java"
        else
            echo -e "${RED}错误: 未找到可用的Java环境${NC}"
            return 1
        fi
    fi
    
    # 根据服务器类型创建不同的启动脚本
    case "$server_type" in
        "vanilla"|"paper"|"spigot")
            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")
            create_forge_start_script "$server_dir" "$java_path" "$mc_version"
            ;;
        "fabric")
            create_fabric_start_script "$server_dir" "$java_path" "$mc_version"
            ;;
        *)
            create_generic_start_script "$server_dir" "$java_path" "$server_type" "$mc_version"
            ;;
    esac
    
    # 保存Java版本信息到配置文件
    save_java_version_config "$server_dir" "$java_path" "$jdk_version"
    
    chmod +x "$server_dir/start.sh"
    echo -e "${GREEN}启动脚本创建完成${NC}"
    return 0
}

# 保存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_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")"

# 加载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

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

# 服务器特定优化
case "$server_type" in
    "paper"|"spigot")
        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"
        ;;
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 "内存: 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")"

# 加载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")"

# 加载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" ]; then
        # Fabric使用特殊的启动方式
        cat > "$server_dir/start.sh" << EOF
#!/bin/bash
# Fabric服务器启动脚本
# Java路径: $java_path

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

# 加载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 "核心文件: fabric-server-launch.jar"
echo "内存分配: 2G-4G"
echo "=========================================="

# 启动Fabric服务器
\$JAVA_PATH \$JVM_OPTS -jar fabric-server-launch.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")"

# 加载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 "内存: 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}"
}

# 创建通用启动脚本
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")"

# 加载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
    
    # 检查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
        
        # 服务器停止后重启管理器
        echo "=========================================="
        echo "服务器已停止，返回管理器..."
        echo "=========================================="
        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 safe_whiptail --yesno "服务器 '$server_name' 配置的Java环境不可用。\n\n是否尝试自动安装JDK $jdk_version？" 12 60; 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 safe_whiptail --yesno "服务器 '$server_name' (版本 $mc_version) 需要JDK $required_jdk，但当前Java环境不可用。\n\n是否立即安装并配置？" 12 60; then
        if install_jdk_version "$required_jdk"; then
            # 配置服务器使用该JDK
            if configure_server_jdk "$server_name" "$required_jdk"; then
                show_msg "成功" "JDK $required_jdk 安装并配置成功"
                return 0
            else
                show_msg "错误" "JDK配置失败"
                return 1
            fi
        else
            show_msg "错误" "JDK安装失败"
            return 1
        fi
    else
        show_msg "信息" "已取消Java环境修复"
        return 1
    fi
}

# =====================================================
#   服务器文件与配置
# =====================================================

# 服务器文件与配置
# 在manage_server_files()函数中添加"快捷设置配置"选项
manage_server_files() {
    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')
    
    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"
    
    # 检查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"
    
    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=$(safe_whiptail --inputbox "请输入服务器端口 (1024-65535):" 10 50 "${current_port:-25565}" 3>&1 1>&2 2>&3)
    
    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
        safe_whiptail --yesno "端口 $new_port 可能已被占用。是否继续使用？" 10 50
        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")
    
    local choice=$(safe_whiptail --menu "选择游戏模式:" 15 40 5 \
        "survival" "生存模式" \
        "creative" "创造模式" \
        "adventure" "冒险模式" \
        "spectator" "观察者模式" \
        3>&1 1>&2 2>&3)
    
    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")
    
    local choice=$(safe_whiptail --menu "选择游戏难度:" 15 50 5 \
        "peaceful" "和平" \
        "easy" "简单" \
        "normal" "普通" \
        "hard" "困难" \
        3>&1 1>&2 2>&3)
    
    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=$(safe_whiptail --inputbox "请输入世界名称:" 10 50 "${current_name:-world}" 3>&1 1>&2 2>&3)
    
    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=$(safe_whiptail --inputbox "请输入服务器显示名称:" 10 50 "${current_name:-Minecraft Server}" 3>&1 1>&2 2>&3)
    
    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=$(safe_whiptail --inputbox "请输入最大玩家数 (1-1000):" 10 50 "${current_players:-20}" 3>&1 1>&2 2>&3)
    
    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=$(safe_whiptail --inputbox "请输入视距 (2-$max_distance):\n\n推荐值:\n- 低性能设备: 4-6\n- 标准服务器: 8-10\n- 高性能服务器: 10-$max_distance" 15 60 "${current_distance:-10}" 3>&1 1>&2 2>&3)
    
    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")
    
    safe_whiptail --yesno "是否启用在线验证？\n\n启用: 只有正版玩家可以加入\n禁用: 允许离线模式玩家加入\n\n当前设置: ${current_mode:-true}" 12 60
    
    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")
    
    safe_whiptail --yesno "是否允许玩家之间互相攻击？\n\n当前设置: ${current_pvp:-true}" 10 50
    
    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"
    
    safe_whiptail --yesno "确定要应用针对 $server_type 服务器的推荐配置吗？\n\n这将根据服务器类型自动优化各项设置。" 12 60
    
    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")
    
    local compression_choice=$(safe_whiptail --menu "选择网络压缩阈值:\n\n值越小压缩越强，-1禁用压缩" 15 50 5 \
        "-1" "禁用压缩 (高性能网络)" \
        "64" "高压缩 (低带宽)" \
        "256" "标准压缩 (推荐)" \
        "512" "低压缩 (高带宽)" \
        3>&1 1>&2 2>&3)
    
    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")
    
    safe_whiptail --yesno "是否启用白名单？\n\n启用后只有白名单中的玩家可以加入服务器。" 10 50
    
    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")
    
    safe_whiptail --yesno "是否允许生成动物？\n\n禁用后世界不会自然生成动物。" 10 50
    
    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")
    
    safe_whiptail --yesno "是否允许生成怪物？\n\n禁用后世界不会自然生成敌对生物。" 10 50
    
    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")
    
    safe_whiptail --yesno "是否允许下界维度？\n\n禁用后玩家无法进入下界。" 10 50
    
    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")
    
    safe_whiptail --yesno "是否生成世界结构？\n\n包括村庄、要塞、神庙等自然生成结构。" 10 50
    
    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")
    
    safe_whiptail --yesno "是否允许飞行？\n\n允许玩家在生存模式下飞行（需要权限）。" 10 50
    
    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=$(safe_whiptail --inputbox "请输入最大tick时间(毫秒):\n\n服务器处理一个tick的最大时间，超时则重启。\n推荐值: $default_value ms" 12 60 "${current_tick_time:-$default_value}" 3>&1 1>&2 2>&3)
    
    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=$(safe_whiptail --inputbox "请输入世界大小限制(区块):\n\n设置世界边界大小，1=1x1区块，29999984=6000x6000区块" 12 60 "${current_size:-29999984}" 3>&1 1>&2 2>&3)
    
    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=$(safe_whiptail --inputbox "请输入模拟距离 (2-$max_distance):\n\n控制实体更新和方块刻的范围，影响性能" 12 60 "${current_distance:-6}" 3>&1 1>&2 2>&3)
    
    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")
    
    local type_choice=$(safe_whiptail --menu "选择世界类型:" 15 50 6 \
        "DEFAULT" "标准世界 (默认)" \
        "FLAT" "超平坦世界" \
        "LARGEBIOMES" "巨型生物群系" \
        "AMPLIFIED" "放大化世界" \
        "CUSTOMIZED" "自定义世界" \
        3>&1 1>&2 2>&3)
    
    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=$(safe_whiptail --inputbox "请输入生成器设置 (JSON格式):\n\n留空使用默认设置" 12 60 "$current_settings" 3>&1 1>&2 2>&3)
    
    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=$(safe_whiptail --inputbox "请输入出生点保护半径 (区块):\n\n0=禁用保护，16=默认保护范围" 12 60 "${current_protection:-16}" 3>&1 1>&2 2>&3)
    
    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=$(safe_whiptail --inputbox "请输入最大建筑高度 (64-$max_height):" 10 50 "${current_height:-$default_height}" 3>&1 1>&2 2>&3)
    
    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=$(safe_whiptail --inputbox "请输入世界种子:\n\n留空使用随机种子" 10 50 "$current_seed" 3>&1 1>&2 2>&3)
    
    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")
    
    safe_whiptail --yesno "是否强制启用白名单？\n\n启用后服务器会自动重新加载白名单。" 10 50
    
    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")
    
    safe_whiptail --yesno "是否启用RCON远程控制？\n\n启用后可以通过网络远程控制服务器。" 10 50
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "enable-rcon" "true"
        
        # 设置RCON端口
        local new_port=$(safe_whiptail --inputbox "请输入RCON端口 (25575-65535):" 10 50 "${current_port:-25575}" 3>&1 1>&2 2>&3)
        if [ $? -eq 0 ] && [ -n "$new_port" ]; then
            set_property_value "$properties_file" "rcon.port" "$new_port"
        fi
        
        # 设置RCON密码
        local new_password=$(safe_whiptail --inputbox "请输入RCON密码:" 10 50 "$current_password" 3>&1 1>&2 2>&3)
        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")
    
    local level_choice=$(safe_whiptail --menu "选择OP权限级别:" 15 50 4 \
        "1" "级别1: 基本命令 (默认)" \
        "2" "级别2: 中级命令" \
        "3" "级别3: 高级命令" \
        "4" "级别4: 所有命令 (包括控制台)" \
        3>&1 1>&2 2>&3)
    
    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")
    
    local choice=$(safe_whiptail --menu "资源包设置:" 15 60 4 \
        "1" "设置资源包URL" \
        "2" "设置资源包哈希" \
        "3" "清除资源包设置" \
        "0" "返回" \
        3>&1 1>&2 2>&3)
    
    case $choice in
        1)
            local new_url=$(safe_whiptail --inputbox "请输入资源包下载URL:" 10 60 "$current_pack" 3>&1 1>&2 2>&3)
            if [ $? -eq 0 ]; then
                set_property_value "$properties_file" "resource-pack" "$new_url"
                show_msg "成功" "资源包URL已设置"
            fi
            ;;
        2)
            local new_hash=$(safe_whiptail --inputbox "请输入资源包SHA-1哈希值:" 10 60 "$current_hash" 3>&1 1>&2 2>&3)
            if [ $? -eq 0 ]; then
                set_property_value "$properties_file" "resource-pack-hash" "$new_hash"
                show_msg "成功" "资源包哈希已设置"
            fi
            ;;
        3)
            safe_whiptail --yesno "确定要清除资源包设置吗？" 8 40
            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")
    
    safe_whiptail --yesno "是否允许向Mojang发送统计数据？\n\n这有助于Mojang改进游戏，但会发送服务器信息。" 12 60
    
    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")
    
    safe_whiptail --yesno "是否启用查询服务？\n\n启用后可以通过UDP查询服务器状态信息。" 12 60
    
    if [ $? -eq 0 ]; then
        set_property_value "$properties_file" "enable-query" "true"
        
        # 设置查询端口
        local new_port=$(safe_whiptail --inputbox "请输入查询服务端口 (默认25565):" 10 50 "${current_port:-25565}" 3>&1 1>&2 2>&3)
        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
        safe_whiptail --msgbox "实体优化设置需要在Paper配置文件中进行。\n\n请使用文件与配置功能编辑 paper.yml 或 spigot.yml 文件。" 12 60
    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
        safe_whiptail --msgbox "区块加载优化设置需要在Paper配置文件中进行。\n\n请使用文件与配置功能编辑 paper.yml 文件中的区块设置。" 12 60
    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)"
    
    safe_whiptail --title "内存优化建议" --msgbox "$message" 15 60
}

# 配置文件验证函数
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
    
    # 选择文件
    selected=$(safe_whiptail --menu "选择要编辑的文件：" 20 60 10 "${files[@]}" 3>&1 1>&2 2>&3)
    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
        safe_whiptail --yesno "文件较大 ($(du -h "$file_path" | cut -f1))，可能不适合编辑。是否继续？" 10 60
        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)
    
    safe_whiptail --title "目录内容: $dir_name" --menu "选择文件：" 20 60 10 "${files[@]}" 3>&1 1>&2 2>&3
}

# 文件操作菜单
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
        safe_whiptail --yesno "文件较大 ($(du -h "$file_path" | cut -f1))，可能不适合编辑。是否继续？" 10 60
        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"
    
    # 确认删除
    safe_whiptail --yesno "确定要删除文件 '$filename' 吗？" 8 40
    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
    
    safe_whiptail --title "服务器核心信息" --msgbox "$info" 15 60
}


# 删除服务器
delete_server() {
    local server_name="$1"
    
    # 确认删除
    safe_whiptail --yesno "确定要删除服务器 '$server_name' 吗？此操作不可恢复！" 8 50
    if [ $? -ne 0 ]; then
        return
    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
    
    # 检查常见的服务器核心文件命名模式
    local possible_jars=(
        "server.jar"
        "*.jar"
        "folia-*.jar"
        "paper-*.jar"
        "spigot-*.jar"
        "bukkit-*.jar"
        "forge-*.jar"
        "fabric-server-launch.jar"
        "minecraft_server.*.jar"
    )
    
    for pattern in "${possible_jars[@]}"; do
        local jars=$(find "$server_dir" -maxdepth 1 -name "$pattern" -type f ! -name "*.log" ! -name "*.txt")
        if [ -n "$jars" ]; then
            # 返回第一个找到的jar文件
            echo "$(basename "$(echo "$jars" | head -1)")"
            return 0
        fi
    done
    
    # 如果没有找到，返回空
    echo ""
}

# 查找合适的Java版本
find_appropriate_java_version() {
    local mc_version=$1
    
    # 根据Minecraft版本选择合适的Java版本
    local major_version=$(echo "$mc_version" | awk -F. '{print $1}')
    
    if [ "$major_version" -ge 21 ] || 
       ([ "$major_version" -eq 1 ] && [ "$(echo "$mc_version" | awk -F. '{print $2}')" -ge 21 ]); then
        echo "21"
    elif [ "$major_version" -ge 17 ] || 
         ([ "$major_version" -eq 1 ] && [ "$(echo "$mc_version" | awk -F. '{print $2}')" -ge 17 ]); then
        echo "17"
    elif [ "$major_version" -ge 11 ] || 
         ([ "$major_version" -eq 1 ] && [ "$(echo "$mc_version" | awk -F. '{print $2}')" -ge 11 ]); then
        echo "11"
    else
        echo "8"
    fi
}


# =====================================================
#   JDK 管理功能
# =====================================================

# JDK 管理菜单
jdk_management() {
    while true; do
        choice=$(safe_whiptail --nocancel --clear \
            --title "JDK 管理" \
            --menu "请选择操作：" 15 50 5 \
            "1" "安装JDK" \
            "2" "管理已安装JDK" \
            "3" "自动配置JDK" \
            "4" "更新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 ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 安装JDK
install_jdk() {
    # 获取可用的JDK版本
    local available_versions=$(get_available_jdk_versions)
    if [ -z "$available_versions" ]; then
        show_msg "错误" "无法获取可用的JDK版本列表"
        return 1
    fi
    
    # 转换为whiptail选项
    local version_list=()
    while IFS= read -r version; do
        version_list+=("$version" "JDK $version")
    done <<< "$available_versions"
    
    # 选择JDK版本
    jdk_version=$(safe_whiptail --menu "选择JDK版本：" 15 40 5 "${version_list[@]}" 3>&1 1>&2 2>&3)
    if [ -z "$jdk_version" ]; then
        return
    fi
    
    # 检查是否已安装
    if jdk_exists "$jdk_version"; then
        show_msg "信息" "JDK $jdk_version 已安装"
        return
    fi
    
    # 选择JDK提供商
    local providers=(
        "adoptium" "Eclipse Temurin"
        "liberica" "BellSoft Liberica"
        "corretto" "Amazon Corretto"
        "zulu" "Azul Zulu"
        "openjdk" "OpenJDK (官方)"
    )
    
    provider=$(safe_whiptail --menu "选择JDK提供商：" 15 40 5 "${providers[@]}" 3>&1 1>&2 2>&3)
    [ $? -ne 0 ] && return
    
    # 对于旧版本，检查提供商支持
    if [ "$jdk_version" -lt 8 ] && [ "$provider" != "openjdk" ]; then
        safe_whiptail --yesno "JDK $jdk_version 是较旧的版本，可能只有OpenJDK提供官方构建。是否继续使用 $provider？" 10 60
        if [ $? -ne 0 ]; then
            provider="openjdk"
        fi
    fi
    
    # 下载并安装JDK
    if install_jdk_version "$jdk_version" "$provider"; then
        show_msg "成功" "JDK $jdk_version 安装成功"
    else
        show_msg "错误" "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"
    
    # 获取下载链接
    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
        # 解压文件
        echo -e "${BLUE}正在解压 JDK...${NC}"
        
        if tar -xzf "$jdk_dir/jdk.tar.gz" -C "$jdk_dir" --strip-components=1; then
            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
}

# 获取 JDK 下载链接
get_jdk_download_url() {
    local jdk_version=$1
    local provider=$2
    local arch=$3
    
    local download_url=""
    
    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_jdk_fallback_url "$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
    
    # 架构映射
    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 获取下载链接
    local download_url=$(echo "$response" | jq -r ".[] | select(.binary.architecture == \"$api_arch\") | .binary.package.link" 2>/dev/null)
    
    if [ -z "$download_url" ] || [ "$download_url" = "null" ]; then
        return 1
    fi
    
    echo "$download_url"
}

# Liberica JDK API (BellSoft)
get_liberica_url() {
    local jdk_version=$1
    local arch=$2
    
    # 架构映射
    case $arch in
        "amd64") api_arch="x86_64" ;;
        "arm64") api_arch="aarch64" ;;
        *) api_arch="x86_64" ;;
    esac
    
    # Liberica API
    local api_url="https://api.bell-sw.com/v1/liberica/releases?version-feature=$jdk_version&os=linux&package-type=tar-gz&arch=$api_arch"
    local response=$(curl -s --connect-timeout 10 "$api_url")
    
    if [ -z "$response" ] || [ "$response" = "null" ]; then
        return 1
    fi
    
    # 解析 JSON 获取下载链接
    local download_url=$(echo "$response" | jq -r '.[0].downloadUrl' 2>/dev/null)
    
    if [ -z "$download_url" ] || [ "$download_url" = "null" ]; then
        return 1
    fi
    
    echo "$download_url"
}

# 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
    
    # 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 获取下载链接
    local download_url=$(echo "$response" | jq -r '.[0].download_url' 2>/dev/null)
    
    if [ -z "$download_url" ] || [ "$download_url" = "null" ]; then
        return 1
    fi
    
    echo "$download_url"
}

# OpenJDK 直接下载链接
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
    
    # OpenJDK 官方构建的下载链接
    case $jdk_version in
        21)
            echo "https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_linux-${api_arch}_bin.tar.gz"
            ;;
        17)
            echo "https://download.java.net/java/GA/jdk17.0.10/9f8c2b7672a4d7c67d6ae8b9e5e5e5e5/9/GPL/openjdk-17.0.10_linux-${api_arch}_bin.tar.gz"
            ;;
        11)
            echo "https://download.java.net/java/GA/jdk11.0.22/7e258dcd7b1e4e2d8e5e5e5e5e5e5e5e/7/GPL/openjdk-11.0.22_linux-${api_arch}_bin.tar.gz"
            ;;
        8)
            if [ "$api_arch" = "x64" ]; then
                echo "https://download.java.net/openjdk/jdk8u41/ri/openjdk-8u41-b04-linux-x64-14_jan_2020.tar.gz"
            else
                # OpenJDK 8 没有官方 ARM64 构建，使用 Adoptium 作为替代
                echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u392-b08/OpenJDK8U-jdk_aarch64_linux_hotspot_8u392b08.tar.gz"
            fi
            ;;
        7)
            if [ "$api_arch" = "x64" ]; then
                echo "https://download.java.net/openjdk/jdk7u80/ri/openjdk-7u80-b15-linux-x64-31_mar_2020.tar.gz"
            else
                # OpenJDK 7 没有官方 ARM64 构建
                echo ""
            fi
            ;;
        6)
            if [ "$api_arch" = "x64" ]; then
                echo "https://download.java.net/openjdk/jdk6/ri/openjdk-6b38-linux-x64-01_apr_2020.tar.gz"
            else
                # OpenJDK 6 没有官方 ARM64 构建
                echo ""
            fi
            ;;
        *)
            echo ""
            ;;
    esac
}

# 验证下载链接是否有效
validate_download_url() {
    local url=$1
    
    # 检查URL格式
    if [[ ! "$url" =~ ^https?:// ]]; then
        return 1
    fi
    
    # 使用HEAD请求检查链接有效性（带超时）
    local status_code=$(curl -s -o /dev/null -w "%{http_code}" -I --connect-timeout 10 -m 10 "$url" 2>/dev/null)
    
    if [ "$status_code" = "200" ] || [ "$status_code" = "302" ] || [ "$status_code" = "307" ]; then
        return 0
    else
        return 1
    fi
}

# 备用下载链接（当所有API都失败时使用）
get_jdk_fallback_url() {
    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
                    
                    # 标记默认JDK
                    local default_marker=""
                    if [ "$jdk_version" = "$DEFAULT_JAVA_VERSION" ]; then
                        default_marker=" (默认)"
                    fi
                    
                    jdks+=("$name" "$provider - $version_info$default_marker")
                    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" "设置为默认" \
            "3" "测试运行" \
            "4" "查看文件" \
            "5" "重新安装" \
            "6" "卸载" \
            "0" "返回" \
            3>&1 1>&2 2>&3)
        
        case $choice in
            1) show_jdk_detailed_info "$selected" ;;
            2) set_default_jdk "$selected" ;;
            3) test_jdk_execution "$selected" ;;
            4) browse_jdk_files "$selected" ;;
            5) reinstall_jdk "$selected" ;;
            6) 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 详细信息 ===\n\n"
    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+="Java版本信息:\n$java_version\n\n"
    
    # 文件系统信息
    if [ -d "$jdk_dir" ]; then
        local dir_size=$(du -sh "$jdk_dir" | cut -f1)
        local file_count=$(find "$jdk_dir" -type f | wc -l)
        local install_time=$(stat -c "%y" "$jdk_dir" | cut -d. -f1)
        
        info+="安装大小: $dir_size\n"
        info+="文件数量: $file_count\n"
        info+="安装时间: $install_time\n\n"
    fi
    
    # 配置信息
    local config_info=$(jq -r --arg name "$jdk_name" '.jdks[] | select(.name == $name)' "$CONFIG_FILE")
    if [ -n "$config_info" ]; then
        local provider=$(echo "$config_info" | jq -r '.provider')
        info+="提供商: $provider\n"
    fi
    
    # 安装信息文件
    if [ -f "$jdk_dir/install.info" ]; then
        info+="\n安装信息:\n"
        info+="$(head -10 "$jdk_dir/install.info")\n"
    fi
    
    # 检查是否为默认JDK
    if [ "$jdk_version" = "$DEFAULT_JAVA_VERSION" ]; then
        info+="\n✅ 这是默认JDK\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")
    fi
    
    if [ ${#using_servers[@]} -gt 0 ]; then
        info+="\n使用此JDK的服务器:\n"
        for server in "${using_servers[@]}"; do
            info+="• $server\n"
        done
    else
        info+="\n⚠️ 没有服务器使用此JDK\n"
    fi
    
    safe_whiptail --title "JDK详细信息: $jdk_name" --msgbox "$info" 20 80
}

# 测试JDK执行
test_jdk_execution() {
    local jdk_name="$1"
    local jdk_dir="$MCJDK_DIR/$jdk_name"
    local java_path="$jdk_dir/bin/java"
    
    if [ ! -f "$java_path" ]; then
        show_msg "错误" "Java可执行文件不存在"
        return 1
    fi
    
    # 保存当前终端设置
    local original_stty=$(stty -g)
    
    # 结束图形界面，恢复终端
    exec 3>&-
    exec 4>&-
    clear
    
    echo -e "${BLUE}测试 JDK: $jdk_name${NC}"
    echo "=========================================="
    
    # 测试Java版本
    echo -e "${GREEN}1. 测试Java版本命令:${NC}"
    "$java_path" -version
    echo ""
    
    # 测试简单Java程序
    echo -e "${GREEN}2. 测试简单Java程序:${NC}"
    local test_java=$(mktemp --suffix=.java)
    cat > "$test_java" << 'EOF'
public class TestJDK {
    public static void main(String[] args) {
        System.out.println("✅ JDK测试成功！");
        System.out.println("Java版本: " + System.getProperty("java.version"));
        System.out.println("JVM供应商: " + System.getProperty("java.vm.vendor"));
        System.out.println("JVM名称: " + System.getProperty("java.vm.name"));
        System.out.println("最大内存: " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "MB");
    }
}
EOF
    
    # 编译测试
    local test_class=$(mktemp)
    if "$jdk_dir/bin/javac" "$test_java" -d "/tmp" 2>/dev/null; then
        echo -e "${GREEN}编译测试: 成功${NC}"
        # 运行测试
        if "$java_path" -cp "/tmp" TestJDK 2>/dev/null; then
            echo -e "${GREEN}运行测试: 成功${NC}"
        else
            echo -e "${RED}运行测试: 失败${NC}"
        fi
        # 清理
        rm -f "/tmp/TestJDK.class" 2>/dev/null
    else
        echo -e "${YELLOW}编译测试: 跳过（javac不可用）${NC}"
    fi
    
    rm -f "$test_java"
    
    # 测试性能
    echo -e "${GREEN}3. 简单性能测试:${NC}"
    local start_time=$(date +%s%N)
    for i in {1..1000}; do
        echo "test" > /dev/null
    done
    local end_time=$(date +%s%N)
    local duration=$(( (end_time - start_time) / 1000000 ))
    echo "执行1000次空操作耗时: ${duration}ms"
    
    echo "=========================================="
    echo -e "${YELLOW}按任意键返回...${NC}"
    read -n 1 -s
    
    # 恢复终端设置
    stty "$original_stty"
}

# 浏览JDK文件
browse_jdk_files() {
    local jdk_name="$1"
    local jdk_dir="$MCJDK_DIR/$jdk_name"
    
    if [ ! -d "$jdk_dir" ]; then
        show_msg "错误" "JDK目录不存在: $jdk_dir"
        return 1
    fi
    
    while true; do
        # 获取JDK目录结构
        local files=()
        local item_count=0
        
        # 添加返回选项
        files+=(".." "返回上级")
        ((item_count++))
        
        # 获取目录内容
        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)
                files+=("$item_name" "文件 - $size")
            fi
            ((item_count++))
            
            # 限制显示数量
            if [ $item_count -gt 30 ]; then
                files+=("..." "更多文件未显示...")
                break
            fi
        done < <(find "$jdk_dir" -maxdepth 1 -print0 2>/dev/null | sort -z)
        
        # 显示文件列表
        selected=$(safe_whiptail --title "浏览JDK文件: $jdk_name" \
            --menu "当前目录: $jdk_dir\n选择文件或目录：" \
            20 70 12 "${files[@]}" 3>&1 1>&2 2>&3)
            
        if [ -z "$selected" ]; then
            return
        fi
        
        if [ "$selected" = ".." ]; then
            return
        elif [ "$selected" = "..." ]; then
            show_msg "信息" "文件数量过多，请使用命令行工具查看"
            continue
        fi
        
        local selected_path="$jdk_dir/$selected"
        
        if [ -d "$selected_path" ]; then
            # 如果是目录，递归进入
            browse_jdk_subdir "$jdk_name" "$selected"
        else
            # 如果是文件，显示文件信息
            show_jdk_file_info "$jdk_name" "$selected"
        fi
    done
}

# 浏览JDK子目录
browse_jdk_subdir() {
    local jdk_name="$1"
    local subdir="$2"
    local jdk_dir="$MCJDK_DIR/$jdk_name"
    local current_dir="$jdk_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)
                files+=("$item_name" "文件 - $size")
            fi
        done < <(find "$current_dir" -maxdepth 1 -print0 2>/dev/null | sort -z)
        
        selected=$(safe_whiptail --title "浏览JDK文件: $jdk_name/$subdir" \
            --menu "当前目录: $current_dir\n选择文件或目录：" \
            20 70 12 "${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
            # 进入子目录
            browse_jdk_subdir "$jdk_name" "$subdir/$selected"
        else
            # 显示文件信息
            show_jdk_file_info "$jdk_name" "$subdir/$selected"
            return
        fi
    done
}

# 显示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
    
    # 显示文件信息
    safe_whiptail --title "文件信息: $filename" --msgbox "$file_info" 15 60
}

# 重新安装JDK
reinstall_jdk() {
    local jdk_name="$1"
    local jdk_version="${jdk_name#jdk}"
    
    # 确认重新安装
    safe_whiptail --yesno "确定要重新安装 JDK $jdk_version 吗？\n\n这将删除当前安装并重新下载。" 10 60
    if [ $? -ne 0 ]; then
        return
    fi
    
    # 获取当前提供商信息
    local current_provider="adoptium"
    local jdk_info=$(jq -r --arg name "$jdk_name" '.jdks[] | select(.name == $name)' "$CONFIG_FILE")
    if [ -n "$jdk_info" ]; then
        current_provider=$(echo "$jdk_info" | jq -r '.provider')
    fi
    
    # 选择提供商
    local providers=(
        "adoptium" "Eclipse Temurin (推荐)"
        "liberica" "BellSoft Liberica"
        "corretto" "Amazon Corretto"
        "zulu" "Azul Zulu"
        "openjdk" "OpenJDK (官方)"
    )
    
    local provider=$(safe_whiptail --menu "选择JDK提供商：" 15 50 5 \
        --default-item "$current_provider" \
        "${providers[@]}" 3>&1 1>&2 2>&3)
    
    [ $? -ne 0 ] && return
    
    # 备份原目录
    local backup_dir="$MCJDK_DIR/$jdk_name.backup.$(date +%Y%m%d_%H%M%S)"
    if [ -d "$MCJDK_DIR/$jdk_name" ]; then
        mv "$MCJDK_DIR/$jdk_name" "$backup_dir"
        echo -e "${GREEN}原安装已备份到: $(basename "$backup_dir")${NC}"
    fi
    
    # 重新安装
    if install_jdk_version "$jdk_version" "$provider"; then
        show_msg "成功" "JDK $jdk_version 重新安装成功"
        
        # 清理备份
        rm -rf "$backup_dir"
    else
        # 恢复备份
        show_msg "错误" "重新安装失败，正在恢复备份..."
        if [ -d "$backup_dir" ]; then
            rm -rf "$MCJDK_DIR/$jdk_name" 2>/dev/null
            mv "$backup_dir" "$MCJDK_DIR/$jdk_name"
            show_msg "成功" "已恢复原安装"
        fi
    fi
}

# 设置默认JDK
set_default_jdk() {
    local jdk_name="$1"
    local jdk_version="${jdk_name#jdk}"
    
    # 验证JDK是否存在
    if ! jdk_exists "$jdk_version"; then
        show_msg "错误" "JDK $jdk_version 不存在或已损坏"
        return 1
    fi
    
    # 更新默认JDK版本
    DEFAULT_JAVA_VERSION="$jdk_version"
    save_config
    
    # 显示设置结果
    local java_path="$MCJDK_DIR/$jdk_name/bin/java"
    local version_info=$("$java_path" -version 2>&1 | head -1)
    
    local message="已将 $jdk_name 设置为默认JDK\n\n"
    message+="版本信息: $version_info\n\n"
    message+="这将影响新创建的服务器和未指定JDK的服务器。"
    
    safe_whiptail --title "设置成功" --msgbox "$message" 12 60
}

# 卸载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
    
    safe_whiptail --yesno "$warning_msg" 20 60
    if [ $? -ne 0 ]; then
        return
    fi
    
    # 确认卸载
    safe_whiptail --yesno "最后确认: 确定要永久删除 JDK $jdk_name 吗？" 10 60
    if [ $? -ne 0 ]; then
        return
    fi
    
    # 执行卸载
    local jdk_dir="$MCJDK_DIR/$jdk_name"
    
    if [ -d "$jdk_dir" ]; then
        # 创建备份（可选）
        safe_whiptail --yesno "是否创建卸载备份？\n\n备份将保存在 $jdk_dir.backup.$(date +%Y%m%d)" 10 60
        if [ $? -eq 0 ]; then
            local backup_dir="$jdk_dir.backup.$(date +%Y%m%d_%H%M%S)"
            cp -r "$jdk_dir" "$backup_dir" 2>/dev/null
            echo -e "${GREEN}已创建备份: $(basename "$backup_dir")${NC}"
        fi
        
        # 删除目录
        if rm -rf "$jdk_dir"; then
            # 从配置中移除
            remove_jdk_from_config "$jdk_name"
            
            # 如果这是默认JDK，清除默认设置
            if [ "$jdk_version" = "$DEFAULT_JAVA_VERSION" ]; then
                DEFAULT_JAVA_VERSION="暂未设置"
                save_config
            fi
            
            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 [ -n "$DEFAULT_JAVA_VERSION" ] && [ "$DEFAULT_JAVA_VERSION" != "暂未设置" ]; then
        if ! jdk_exists "$DEFAULT_JAVA_VERSION"; then
            echo -e "${YELLOW}警告: 默认JDK $DEFAULT_JAVA_VERSION 不存在${NC}"
            ((issues_found++))
            
            if safe_whiptail --yesno "默认JDK $DEFAULT_JAVA_VERSION 不存在。是否尝试重新安装？" 10 60; then
                if install_jdk_version "$DEFAULT_JAVA_VERSION"; then
                    echo -e "${GREEN}默认JDK重新安装成功${NC}"
                    ((fixed_issues++))
                else
                    echo -e "${RED}默认JDK重新安装失败${NC}"
                    # 清除无效的默认设置
                    DEFAULT_JAVA_VERSION="暂未设置"
                    save_config
                fi
            fi
        fi
    fi
    
    # 检查配置中的所有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 safe_whiptail --yesno "配置中的JDK $name 不存在。是否尝试重新安装？" 10 60; 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 safe_whiptail --yesno "是否从配置中移除无效的JDK $name？" 10 60; 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 safe_whiptail --yesno "服务器 '$server_name' 使用的JDK $server_jdk 不存在。\n\nMinecraft版本: $mc_version\n需要JDK版本: $required_jdk\n\n是否自动安装并配置正确的JDK？" 15 60; 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}"
        safe_whiptail --msgbox "JDK环境检查完成，未发现问题" 10 40
    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
        
        safe_whiptail --msgbox "$summary" 12 50
    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
            show_msg "信息" "没有可用的服务器"
            return
        fi
        
        selected=$(safe_whiptail --menu "选择要配置JDK的服务器：" 15 50 6 "${servers[@]}" 3>&1 1>&2 2>&3)
        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建议
        local jdk_info="服务器: $selected\n"
        jdk_info+="Minecraft版本: $mc_version\n"
        jdk_info+="服务器类型: $server_type\n"
        jdk_info+="必需JDK版本: $required_jdk\n"
        jdk_info+="推荐JDK版本: $recommended_jdk\n\n"
        
        if [ "$required_jdk" != "$recommended_jdk" ]; then
            jdk_info+="${YELLOW}注意: 推荐使用JDK $recommended_jdk 以获得最佳性能${NC}"
        fi
        
        safe_whiptail --title "JDK配置建议" --msgbox "$jdk_info" 15 50
        
        # 选择要使用的JDK版本
        local jdk_choice=$(safe_whiptail --menu "选择JDK版本：" 15 40 5 \
            "$required_jdk" "必需版本" \
            "$recommended_jdk" "推荐版本" \
            "custom" "自定义版本" \
            3>&1 1>&2 2>&3)
        
        local final_jdk_version="$required_jdk"
        
        case "$jdk_choice" in
            "custom")
                local custom_jdk=$(safe_whiptail --inputbox "请输入自定义JDK版本：" 10 40 "$recommended_jdk" 3>&1 1>&2 2>&3)
                if [ -n "$custom_jdk" ] && validate_jdk_version "$custom_jdk"; then
                    final_jdk_version="$custom_jdk"
                else
                    show_msg "错误" "无效的JDK版本"
                    return
                fi
                ;;
            "$recommended_jdk")
                final_jdk_version="$recommended_jdk"
                ;;
            *)
                final_jdk_version="$required_jdk"
                ;;
        esac
        
        # 检查是否已安装所需JDK
        if ! jdk_exists "$final_jdk_version"; then
            # 询问是否安装
            safe_whiptail --yesno "需要JDK $final_jdk_version，但未安装。是否立即安装？" 10 50
            if [ $? -eq 0 ]; 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版本。"
            
            safe_whiptail --title "配置完成" --msgbox "$config_info" 15 50
        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
            ;;
        "bukkit"|"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}"
        safe_whiptail --yesno "Minecraft $mc_version 与 JDK $jdk_version 可能存在兼容性问题。是否继续？" 10 60
        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"
    
    safe_whiptail --title "JDK版本列表" --msgbox "$message" 15 40
    show_msg "成功" "JDK版本列表已更新"
}

# =====================================================
#   内网穿透管理功能
# =====================================================

# HPPRO 内网穿透管理菜单
hp_management() {
    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_statusd="未下载"
        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" "打开内网穿透官网" \
            "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) open_hp_website ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}


# 打开HPPRO官网
open_hp_website() {
    local hp_website="https://www.hpproxy.cn/#/"  # 根据链接1设置的官网
    
    # 显示官网信息并提供打开选项
    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系统（如果通过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
}

# 初始化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服务
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=$(safe_whiptail --inputbox "当前设备ID: $current_id\n请输入新的设备ID:" 10 50 "$current_id" 3>&1 1>&2 2>&3)
    else
        new_id=$(safe_whiptail --inputbox "请输入设备ID:" 8 50 3>&1 1>&2 2>&3)
    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() {
    safe_whiptail --yesno "确定要下载/更新客户端吗？" 8 50
    [ $? -ne 0 ] && return
    
    # 确定下载URL
    local hp_url
    if [ "$ARCH" = "amd64" ]; then
        hp_url="http://wpv4.hycexit.xyz/down.php/f64242518348858edb091749a5dd7793"
    elif [ "$ARCH" = "arm64" ]; then
        hp_url="http://wpv4.hycexit.xyz/down.php/ad175853548232332aa8e7d565606c23"
    else
        show_msg "错误" "不支持的架构: $ARCH"
        return 1
    fi
    
    # 下载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客户端下载失败${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=$(safe_whiptail --inputbox "请输入要搜索的关键词：" 8 60 3>&1 1>&2 2>&3)
    [ -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"
    
    safe_whiptail --title "日志统计信息" --msgbox "$stats" 15 60
}

# 导出日志文件
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=$(safe_whiptail --inputbox "请输入导出路径：" 8 60 "$default_path" 3>&1 1>&2 2>&3)
    [ -z "$export_path" ] && return
    
    # 检查目标目录是否存在
    local export_dir=$(dirname "$export_path")
    if [ ! -d "$export_dir" ]; then
        safe_whiptail --yesno "目录不存在，是否创建？" 8 50
        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
    
    # 确认操作
    safe_whiptail --yesno "确定要清空 HPPRO 日志文件吗？此操作不可恢复！" 8 50
    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() {
    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
}

# 清理缓存文件函数
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)
    
    # 显示清理选项
    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"
        
        safe_whiptail --yesno "确定要清理 $temp_count 个临时文件吗？\n\n预计释放空间: $(echo "scale=2; $freed_space/1024/1024" | bc)MB" 10 60
        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
            safe_whiptail --yesno "找到 $clean_count 个超过${keep_days}天的旧日志文件\n\n确定要清理吗？\n预计释放空间: $(echo "scale=2; $freed_space/1024/1024" | bc)MB" 12 60
            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() {
    safe_whiptail --yesno "确定要清理所有缓存文件吗？\n\n这将包括:\n• 临时文件\n• 旧日志文件\n• 下载缓存\n• 备份文件\n\n此操作不可恢复！" 15 60
    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"
    
    safe_whiptail --title "缓存文件详情" --msgbox "$details" 20 70
}

# 定期自动清理函数（可在后台运行）
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
}

# =====================================================
#   管理器更新功能（基于 GitHub Releases）
# =====================================================

# 更新管理器主函数
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")

    if [ -z "$latest_tag" ]; then
        echo -e "${RED}❌ 未找到 release 标签（可能仓库不存在或 Token 无效）${NC}"
        echo -e "${RED}⚠️ 请检查你的 GitHub Token 和仓库设置！${NC}"
        return 1
    fi

    if [ -z "$download_url" ]; then
        echo -e "${RED}❌ 在 release $latest_tag 中未找到文件 '$SCRIPT_NAME'${NC}"
        echo -e "${YELLOW}请确保在 GitHub Release 中上传了该脚本${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

    if [ "$(echo -e "$latest_version\n$current_version" | sort -V | head -n1)" = "$latest_version" ]; then
        if [ "$NO_GUI" != "true" ]; then
            show_msg "发现新版本" "发现新版本: $latest_version (当前: $current_version)"
        else
            echo -e "${YELLOW}📢 发现新版本: $latest_version (当前: $current_version)${NC}"
        fi
    else
        if [ "$NO_GUI" != "true" ]; then
            show_msg "警告" "本地版本 ($current_version) 高于最新版本 ($latest_version)\n请检查你的脚本版本设置"
        else
            echo -e "${YELLOW}⚠️ 本地版本 ($current_version) > 最新版本 ($latest_version)${NC}"
            echo -e "${YELLOW}请检查你的脚本版本设置${NC}"
        fi
        return 0
    fi

    # === 用户确认更新 ===
    if [ "$NO_GUI" != "true" ]; then
        if ! safe_whiptail --yesno "是否更新到 $latest_tag?" 12 40; 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"
    echo -e "${BLUE}⬇️ 正在下载新版本 ($latest_tag)...${NC}"

    if curl -L -H "Authorization: Bearer $GITHUB_TOKEN" -o "$tmp_file" --progress-bar "$download_url"; then
        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
        return 0
    else
        echo -e "${RED}❌ 下载失败！${NC}"
        rm -f "$tmp_file"
        return 1
    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"
    
    # 显示信息
    safe_whiptail --title "系统信息" --msgbox "$info" 25 80
}

# =====================================================
#   常见问题解答功能
# =====================================================

# 常见问题解答菜单
show_faq() {
    while true; do
        choice=$(safe_whiptail --nocancel --clear \
            --title "常见问题解答" \
            --menu "请选择问题类别：" 25 80 15 \
            "1" "服务器相关问题" \
            "2" "网络与连接问题" \
            "3" "插件与模组问题" \
            "4" "性能优化建议" \
            "5" "脚本使用与故障排除" \
            "6" "资源管理与优化" \
            "7" "备份与迁移问题" \
            "8" "安全相关问题" \
            "0" "返回主菜单" \
            3>&1 1>&2 2>&3)
        
        [ $? -ne 0 ] && break
        
        case $choice in
            1) show_server_faq ;;
            2) show_network_faq ;;
            3) show_plugin_faq ;;
            4) show_performance_faq ;;
            5) show_script_faq ;;
            6) show_resource_faq ;;
            7) show_backup_faq ;;
            8) show_security_faq ;;
            0) return ;;
            *) show_msg "错误" "无效选项" ;;
        esac
    done
}

# 服务器相关问题
show_server_faq() {
    local faq_file=$(mktemp)
    cat > "$faq_file" << 'EOF'
Q: 服务器启动失败怎么办？
A: 1. 检查Java版本是否兼容
   2. 检查服务器核心文件是否完整
   3. 查看日志文件获取详细错误信息
   4. 确保有足够的内存和存储空间
   5. 检查端口是否被占用

Q: 如何备份服务器？
A: 1. 使用服务器管理菜单中的备份功能
   2. 手动备份服务器目录
   3. 定期备份重要配置文件
   4. 使用版本控制管理配置变更

Q: 如何更改服务器端口？
A: 1. 编辑server.properties文件中的server-port选项
   2. 默认端口是25565，可更改为1024-65535之间的任意端口
   3. 更改后需重启服务器生效
   4. 确保防火墙开放新端口

Q: 如何设置管理员？
A: 1. 在ops.txt文件中添加玩家用户名
   2. 使用op <玩家名>命令
   3. 在控制台或游戏内授予权限
   4. 使用权限插件进行更精细的权限管理

Q: 服务器崩溃后如何恢复？
A: 1. 查看崩溃日志确定原因
   2. 回滚到最近的备份
   3. 移除可能导致崩溃的插件/模组
   4. 检查系统资源是否充足
   5. 更新有问题的软件版本

Q: 如何查看服务器日志？
A: 1. 使用管理器的日志查看功能
   2. 直接查看服务器目录下的logs文件夹
   3. 使用tail -f命令实时查看日志
   4. 日志文件通常按日期分割，如latest.log

Q: 如何更新服务器版本？
A: 1. 备份当前服务器
   2. 下载新版本服务器核心
   3. 替换旧的核心文件
   4. 更新插件/模组到兼容版本
   5. 测试运行确保稳定性

Q: 如何提高服务器性能？
A: 1. 分配更多内存给服务器
   2. 使用性能优化的服务端（如Paper）
   3. 减少视距和实体数量
   4. 使用性能优化插件
   5. 优化世界设置和生成边界

Q: 服务器内存不足怎么办？
A: 1. 增加Xmx参数值分配更多内存
   2. 使用内存优化插件
   3. 减少同时在线玩家数量
   4. 限制实体和区块加载
   5. 定期重启释放内存

Q: 如何减少服务器延迟？
A: 1. 使用更近的服务器地理位置
   2. 优化网络连接
   3. 减少红石机械和实体数量
   4. 使用延迟优化插件
   5. 优化数据库查询和文件IO
EOF
    
    safe_whiptail --title "服务器相关问题" --textbox "$faq_file" 25 80
    rm -f "$faq_file"
}

# 网络与连接问题
show_network_faq() {
    local faq_file=$(mktemp)
    cat > "$faq_file" << 'EOF'
Q: 如何让朋友连接到我的服务器？
A: 1. 使用内网穿透功能
   2. 确保路由器端口转发正确设置
   3. 检查防火墙设置
   4. 提供正确的IP地址和端口
   5. 测试连接是否通畅

Q: 内网穿透连接不稳定怎么办？
A: 1. 检查网络连接稳定性
   2. 尝试更换内网服务提供商
   3. 联系服务提供商寻求技术支持
   4. 检查设备ID配置是否正确
   5. 更新内网穿透客户端到最新版本

Q: 如何测试服务器连接？
A: 1. 使用Minecraft客户端直接连接
   2. 使用telnet或nc命令测试端口
   3. 使用在线端口检查工具
   4. 检查服务器日志中的连接记录
   5. 使用ping命令测试网络连通性

Q: 移动网络下如何提高连接稳定性？
A: 1. 使用稳定的4G/5G网络，避免信号弱区
   2. 设置APN协议为IPv4/IPv6
   3. 避免网络切换：关闭WiFi自动切换
   4. 使用UDP优化：考虑使用KCP加速

Q: 如何测试端口是否开放？
A: 1. 本地测试：telnet localhost 端口号
   2. 外部测试：使用 curl ifconfig.me 获取IP，让他人测试
   3. 在线工具：使用 portchecktool.com 等网站
   4. 应用检测：使用网络调试助手类APP

Q: 为什么朋友无法通过公网IP连接？
A: 1. 运营商限制：移动网络大多使用NAT，需要内网穿透
   2. 防火墙限制：检查手机或路由器的防火墙设置
   3. 端口冲突：确保没有其他程序占用相同端口
   4. 绑定地址：检查 server.properties 中 server-ip 设置
EOF
    
    safe_whiptail --title "网络与连接问题" --textbox "$faq_file" 25 80
    rm -f "$faq_file"
}

# 插件与模组问题
show_plugin_faq() {
    local faq_file=$(mktemp)
    cat > "$faq_file" << 'EOF'
Q: 插件不兼容怎么办？
A: 1. 确保插件版本与服务器版本匹配
   2. 检查插件依赖是否满足
   3. 查看插件文档或寻求支持
   4. 尝试使用兼容性版本或替代插件
   5. 检查插件配置是否正确

Q: 模组导致服务器崩溃怎么办？
A: 1. 逐个移除模组以确定问题模组
   2. 检查模组兼容性
   3. 确保所有模组使用相同加载器
   4. 检查模组依赖关系
   5. 查看崩溃报告确定具体问题

Q: 如何更新插件/模组？
A: 1. 手动下载新版本替换旧文件
   2. 备份当前配置和数据库
   3. 测试更新后功能是否正常
   4. 注意版本兼容性

Q: 如何解决插件冲突？
A: 1. 逐个禁用：每次禁用一个插件测试稳定性
   2. 查看错误日志：寻找冲突的具体类和错误信息
   3. 版本匹配：确保所有插件支持当前服务端版本
   4. 依赖检查：确保所有必需的前置插件已安装

Q: 模组服务器启动失败怎么办？
A: 1. 检查Forge/Fabric版本：确保与模组兼容
   2. 内存分配：模组需要更多内存，增加 -Xmx 值
   3. 核心模组：确保必需的核心模组已安装
   4. 配置文件：检查 config/ 目录中的模组配置
EOF
    
    safe_whiptail --title "插件与模组问题" --textbox "$faq_file" 25 80
    rm -f "$faq_file"
}

# 性能优化建议
show_performance_faq() {
    local faq_file=$(mktemp)
    cat > "$faq_file" << 'EOF'
Q: 如何提高服务器性能？
A: 1. 分配更多内存给服务器
   2. 使用性能优化的服务端（如Paper）
   3. 减少视距和实体数量
   4. 使用性能优化插件
   5. 优化世界设置和生成边界

Q: 服务器内存不足怎么办？
A: 1. 增加Xmx参数值分配更多内存
   2. 使用内存优化插件
   3. 减少同时在线玩家数量
   4. 限制实体和区块加载
   5. 定期重启释放内存

Q: 如何减少服务器延迟？
A: 1. 使用更近的服务器地理位置
   2. 优化网络连接
   3. 减少红石机械和实体数量
   4. 使用延迟优化插件
   5. 优化数据库查询和文件IO

Q: 如何提高手机上的服务器性能？
A: 1. 使用Paper服务端：针对性能有显著优化
   2. 视图距离：设置为4-6，不要超过8
   3. 实体限制：使用插件限制生物和物品实体数量
   4. 预生成地形：使用WorldBorder插件预生成世界

Q: TPS过低如何优化？
A: 1. 性能分析：使用 /timings report 找出性能瓶颈
   2. 红石机械：限制或优化复杂红石电路
   3. 农场优化：减少同时运行的自动农场
   4. 插件优化：禁用或更换性能差的插件
EOF
    
    safe_whiptail --title "性能优化建议" --textbox "$faq_file" 25 80
    rm -f "$faq_file"
}

# 脚本使用与故障排除
show_script_faq() {
    local faq_file=$(mktemp)
    cat > "$faq_file" << 'EOF'
Q: 脚本启动时报错"command not found"怎么办？
A: 1. 确保已安装所有依赖：curl, wget, jq, unzip, tar, whiptail, bc
   2. Linux系统中使用对应包管理器安装
   3. 检查PATH环境变量是否正确设置

Q: 图形界面显示异常或乱码怎么办？
A: 1. 检查终端尺寸：调整窗口大小或使用 resize 命令
   2. 编码问题：确保终端使用UTF-8编码
   3. 使用命令行模式：添加 --no-gui 参数
   4. 更换终端应用：建议使用官方应用或标准Linux终端

Q: 如何查看详细的错误日志？
A: 1. 查看管理器日志：cat ~/.mcmanager/logs/manager_*.log
   2. 服务器日志：在服务器目录的 logs/ 文件夹中
   3. 启用调试模式：使用 -d 或 --debug 参数运行脚本
   4. 检查系统日志：logcat (Android) 或 journalctl (Linux)

Q: 脚本更新失败怎么办？
A: 1. 检查网络连接是否正常
   2. 手动下载最新版本替换
   3. 检查脚本执行权限：chmod +x script.sh
   4. 查看更新日志了解变更内容

Q: 如何恢复默认配置？
A: 1. 删除配置文件：rm ~/.mcmanager/config.json
   2. 重新运行脚本生成默认配置
   3. 备份重要配置后再重置
   4. 使用 --reset 参数重置管理器
EOF
    
    safe_whiptail --title "脚本使用与故障排除" --textbox "$faq_file" 25 80
    rm -f "$faq_file"
}

# 资源管理与优化
show_resource_faq() {
    local faq_file=$(m极速emp)
    cat > "$faq_file" << 'EOF'
Q: 手机内存不足导致服务器崩溃怎么办？
A: 1. 调整JVM参数：减少 -Xmx 内存分配（如从2G改为1G）
   2. 使用轻量级服务端：选择Paper而不是Forge
   3. 优化世界设置：减少视距、限制实体数量
   4. 定期重启：设置定时重启释放内存

Q: 存储空间不足如何清理？
A: 1. 清理旧日志：删除服务器目录中旧的 .log.gz 文件
   2. 删除旧备份：管理备份文件，只保留最新几个
   3. 清理下载缓存：检查 ~/.mcmanager/cache/ 目录
   4. 使用世界边界：限制世界大小避免无限扩展

Q: 如何监控服务器资源使用情况？
A: 1. 使用 top 或 htop 查看CPU和内存使用
   2. 服务器内置：使用 timings 命令（Paper）或 spark 插件
   3. 日志分析：检查tps和内存使用记录

Q: 如何优化电池使用？
A: 1. 连接电源时运行服务器
   2. 降低服务器性能要求：减少视距和实体
   3. 使用省电模式：调整CPU频率和屏幕亮度
   4. 限制后台活动：关闭不必要的后台应用

Q: CPU使用率过高如何解决？
A: 1. 找出高CPU进程：使用 top 命令查看
   2. 优化红石电路：减少复杂红石机械
   3. 限制实体生成：控制生物和物品实体数量
   4. 使用性能分析工具定位瓶颈
EOF
    
    safe_whiptail --title "资源管理与优化" --textbox "$faq_file" 25 80
    rm -f "$faq_file"
}

# 备份与迁移问题
show_backup_faq() {
    local faq_file=$(mktemp)
    cat > "$faq_file" << 'EOF'
Q: 如何将服务器迁移到新设备？
A: 1. 完整备份：使用脚本的备份功能或打包整个服务器目录
   2. 配置文件：备份 server.properties、ops.txt 等重要文件
   3. 数据库：如果有插件数据库，导出SQL文件
   4. 测试恢复：在新设备上测试备份是否完整可用

Q: 自动备份失败怎么办？
A: 1. 存储权限：确保有写入备份目录的权限
   2. 空间检查：确保目标磁盘有足够空间
   3. 路径验证：检查备份路径配置是否正确
   4. 手动测试：尝试手动执行备份命令排查问题

Q: 如何设置自动备份计划？
A: 1. 使用系统的定时任务功能（cron或Tasker）
   2. 配置备份频率和保留策略
   3. 测试备份脚本是否正常工作
   4. 监控备份任务执行情况

Q: 备份文件太大怎么办？
A: 1. 使用压缩备份：tar -zcf 压缩备份文件
   2. 排除不必要的文件：如缓存、日志文件
   3. 增量备份：只备份变更部分
   4. 分卷备份：将大备份分割成多个小文件

Q: 如何验证备份的完整性？
A: 1. 定期测试恢复备份
   2. 检查备份文件大小和修改时间
   3. 使用校验和验证文件完整性
   4. 多地存储：在不同设备上保存备份副本
EOF
    
    safe_whiptail --title "备份与迁移问题" --textbox "$faq_file" 25 80
    rm -f "$faq_file"
}

# 安全相关问题
show_security_faq() {
    local faq_file=$(mktemp)
    cat > "$faq_file" << 'EOF'
Q: 如何提高服务器安全性？
A: 1. 定期更新：保持服务端和插件为最新版本
   2. 权限管理：使用权限插件精细控制玩家权限
   3. 防火墙设置：限制不必要的端口访问
   4. 日志监控：定期检查日志可疑活动
   5. 备份策略：定期备份重要数据

Q: 服务器被攻击怎么办？
A: 1. 立即隔离：断开网络连接或停止服务器
   2. 日志分析：检查攻击来源和方式
   3. 恢复备份：从干净备份恢复服务器
   4. 安全加固：更新所有软件，修改所有密码
   5. 寻求帮助：向社区或安全专家咨询

Q: 如何防止未授权访问？
A: 1. 设置强密码：使用复杂的管理员密码
   2. 白名单制度：只允许已知玩家加入
   3. 权限控制：按需分配权限，避免过度授权
   4. 网络隔离：将服务器放在受保护的网络环境中

Q: 如何保护玩家数据？
A: 1. 数据加密：敏感信息加密存储
   2. 访问控制：限制对玩家数据的访问权限
   3. 定期备份：防止数据丢失
   4. 隐私政策：明确数据收集和使用规则

Q: 如何应对DDoS攻击？
A: 1. 使用云防护服务：如Cloudflare等DDoS防护
   2. 限制连接频率：防止大量连接请求
   3. 隐藏真实IP：使用代理或CDN服务
   4. 应急计划：准备备用服务器和网络
EOF
    
    safe_whiptail --title "安全相关问题" --textbox "$faq_file" 25 80
    rm -f "$faq_file"
}

# =====================================================
#   主程序入口和初始化
# =====================================================

# 主程序入口
main() {
    # 解析命令行参数
    parse_arguments "$@"
    
    # 初始化检查
    init_checks
    
    # 调试模式
    if [ "$DEBUG_MODE" = "true" ]; then
        set -x
    fi
    
    # 无GUI模式处理
    if [ "$NO_GUI" = "true" ]; then
        handle_no_gui_mode
        return
    fi
    
    # 跳过欢迎界面
    if [ "$SKIP_WELCOME" != "true" ]; then
        show_welcome
    fi
    
    # 处理目标菜单或函数
    if [ -n "$TARGET_MENU" ] || [ -n "$TARGET_FUNCTION" ] || [ -n "$GOTO_MENU" ]; then
        handle_target_execution
    else
        # 正常进入主菜单
        main_menu
    fi
}

# =====================================================
#   脚本执行入口
# =====================================================

# 保存原始终端设置
original_term=$(stty -g)

# 设置信号处理
trap 'stty "$original_term"; cleanup_on_exit' EXIT SIGINT SIGTERM
trap 'echo -e "${RED}操作已中断${NC}"; exit 1' INT TERM
trap 'error_handler $LINENO' ERR

# 获取脚本路径
SCRIPT_PATH=$(get_script_path)
SCRIPT_DIR=$(dirname "$SCRIPT_PATH")

# 全局变量初始化
TARGET_MENU=""
TARGET_FUNCTION=""
GOTO_MENU=""
SERVER_NAME=""
JDK_VERSION=""
SKIP_WELCOME="false"
SKIP_MAIN_MENU="false"
DEBUG_MODE="false"
NO_GUI="false"

# 主执行
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
    if [ -t 0 ]; then
        main "$@"
    else
        echo "请在交互式终端中运行此脚本"
        exit 1
    fi
fi












