#!/bin/bash
# dst-admin-go饥荒面板多功能安装脚本 v5.2 爱来自 伶依nekochan 抖音 ACFUN同名主播
# 本脚本部分代码由deepseek生成 有问题请进群告诉我 737331541 记得上传日志

# 获取用户信息
REAL_user=$(who am i | awk '{print $1}')
home_dir=$(getent passwd $REAL_user | cut -d: -f6)
dest_dir="$home_dir/dst"
manual_dir="$dest_dir/dest_dir/手动上传"
log_dir="$(pwd)/install_logs"
log_file="$log_dir/dst_install_$(date +%Y%m%d%H%M%S).log"
bench_dir="$home_dir/geekbench"
steamcmd_dir="$home_dir/steamcmd"  

# 颜色输出函数
red_echo() {
    echo -e "\033[31m$1\033[0m"
}

green_echo() {
    echo -e "\033[32m$1\033[0m"
}

yellow_echo() {
    echo -e "\033[33m$1\033[0m"
}

blue_echo() {
    echo -e "\033[34m$1\033[0m"
}

# 询问函数
ask_yes_no() {
    local prompt="$1"
    local default="$2"
    local reply
    
    while true; do
        if [ "$default" = "Y" ]; then
            read -p "$prompt [Y/n]: " reply
        else
            read -p "$prompt [y/N]: " reply
        fi
        
        if [ -z "$reply" ]; then
            reply="$default"
        fi
        
        case "$reply" in
            [Yy]* ) return 0 ;;
            [Nn]* ) return 1 ;;
            * ) echo "请输入 y 或 n." ;;
        esac
    done
}

# --- 设置系统虚拟内存 ---
set_swap_memory() {
    echo "====== 设置系统虚拟内存 ======"
    
    # 检查是否已设置过虚拟内存的标志
    swap_flag="$home_dir/.swap_set"
    
    # 添加卸载选项
    if [ -f /swapfile ] || [ -f "$swap_flag" ]; then
        echo "检测到系统已设置虚拟内存，请选择操作："
        echo "1) 重新设置虚拟内存"
        echo "2) 卸载虚拟内存"
        echo "3) 跳过操作"
        read -p "请输入选项 (1-3): " operation_choice
        
        case $operation_choice in
            1)
                echo "您选择了重新设置虚拟内存"
                ;;
            2)
                echo "开始卸载虚拟内存..."
                if [ -f /swapfile ]; then
                    sudo swapoff /swapfile 2>/dev/null
                    sudo rm -f /swapfile
                    echo "已删除交换文件"
                fi
                # 从fstab中删除交换文件配置
                sudo sed -i '/\/swapfile/d' /etc/fstab
                # 删除标志文件
                rm -f "$swap_flag" 2>/dev/null
                green_echo "虚拟内存已成功卸载！"
                echo "当前内存状态："
                free -h
                return 0
                ;;
            3)
                echo "已跳过虚拟内存操作"
                return 0
                ;;
            *)
                red_echo "无效选择，使用默认操作：重新设置"
                ;;
        esac
    fi
    
    # 首次安装时的跳过选项
    if [ ! -f "$swap_flag" ]; then
        yellow_echo "首次安装，建议设置虚拟内存以提升服务器性能"
        if ! ask_yes_no "是否现在设置虚拟内存？" "Y"; then
            echo "已跳过虚拟内存设置"
            return 0
        fi
    fi
    
    # 获取服务器内存大小（MB）
    total_memory=$(free -m | awk '/Mem:/ {print $2}')
    echo "检测到物理内存: $total_memory MB"
    
    # 确定交换分区大小 - 修改为提供多种选项
    echo "请选择虚拟内存大小设置："
    echo "1) 物理内存的一半 (${total_memory}/2 = $((total_memory / 2)) MB)"
    echo "2) 与物理内存相同 (${total_memory} MB)"
    echo "3) 物理内存的两倍 (${total_memory}*2 = $((total_memory * 2)) MB)"
    echo "4) 自定义大小"
    echo "5) 取消设置"
    read -p "请输入选项 (1-5): " choice
    
    case $choice in
        1)
            swap_size=$((total_memory / 2))
            ;;
        2)
            swap_size=$total_memory
            ;;
        3)
            swap_size=$((total_memory * 2))
            ;;
        4)
            while true; do
                read -p "请输入虚拟内存大小 (MB，建议不小于 ${total_memory}): " custom_swap
                if [[ $custom_swap =~ ^[0-9]+$ ]] && [ $custom_swap -ge 512 ]; then
                    swap_size=$custom_swap
                    break
                else
                    red_echo "请输入有效的数字（至少512MB）"
                fi
            done
            ;;
        5)
            echo "已取消虚拟内存设置"
            return 0
            ;;
        *)
            red_echo "无效选择，使用默认值：物理内存的一半"
            swap_size=$((total_memory / 2))
            ;;
    esac
    
    echo "设置虚拟内存大小为: ${swap_size}MB"
    
    # 检查是否已有交换文件
    if [ -f /swapfile ]; then
        echo "检测到已存在交换文件，删除旧文件..."
        sudo swapoff /swapfile
        sudo rm -f /swapfile
    fi
    
    # 创建交换文件
    echo "创建 ${swap_size}MB 的交换文件..."
    if ! sudo dd if=/dev/zero of=/swapfile bs=1M count=$swap_size status=progress; then
        red_echo "创建交换文件失败！"
        return 1
    fi
    
    # 设置权限
    sudo chmod 600 /swapfile
    
    # 格式化交换文件
    echo "格式化交换文件..."
    if ! sudo mkswap /swapfile; then
        red_echo "格式化交换文件失败！"
        sudo rm -f /swapfile
        return 1
    fi
    
    # 启用交换文件
    echo "启用交换文件..."
    if ! sudo swapon /swapfile; then
        red_echo "启用交换文件失败！"
        sudo rm -f /swapfile
        return 1
    fi
    
    # 设置开机自动挂载
    echo "设置开机自动挂载交换文件..."
    if ! grep -q "/swapfile" /etc/fstab; then
        echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
    else
        echo "交换文件已在fstab中，无需重复添加"
    fi
    
    # 创建已设置标志
    touch "$swap_flag"
    
    echo "虚拟内存设置完成！"
    free -h
}

# --- 更改 APT 软件源 ---
change_apt_source() {
    # 检测是否已安装面板，若已安装则跳过源设置
    panel_flag="$home_dir/.dst_panel_installed"
    if [ -f "$panel_flag" ]; then
        yellow_echo "检测到面板已安装，跳过软件源设置步骤"
        return 0
    fi

    # 检查是否为 Ubuntu 系统
    if ! grep -q "Ubuntu" /etc/issue 2>/dev/null; then
        yellow_echo "非 Ubuntu 系统，跳过更换软件源步骤。"
        return 0
    fi

    yellow_echo "----------------------------------------------------------------"
    yellow_echo "为了提升后续软件包的下载速度，可选择更换为国内镜像源。"
    yellow_echo "此操作将备份当前的源列表，支持多种国内镜像选择。"
    yellow_echo "----------------------------------------------------------------"
    
    # 提供源选择，默认中科大源
    echo "请选择要使用的软件源（默认：中科大源）："
    echo "1) 中科大源 (mirrors.ustc.edu.cn)"
    echo "2) 腾讯云源 (mirrors.cloud.tencent.com)"
    echo "3) 阿里云源 (mirrors.aliyun.com)"
    echo "4) 南京大学源 (mirror.nju.edu.cn)"
    echo "5) 跳过更换源"
    read -p "请输入选项 (1-5，默认1): " source_choice
    source_choice=${source_choice:-1}  # 默认选择中科大源

    # 处理跳过选项
    if [ "$source_choice" -eq 5 ]; then
        green_echo "已选择跳过更换软件源。"
        return 0
    fi

    # 验证选项有效性
    if ! [[ "$source_choice" =~ ^[1-4]$ ]]; then
        red_echo "无效选择，默认使用中科大源"
        source_choice=1
    fi

    # 定义各源地址
    case $source_choice in
        1)
            mirror="https://mirrors.ustc.edu.cn/ubuntu/"
            mirror_name="中科大"
            ;;
        2)
            mirror="https://mirrors.cloud.tencent.com/ubuntu/"
            mirror_name="腾讯云"
            ;;
        3)
            mirror="https://mirrors.aliyun.com/ubuntu/"
            mirror_name="阿里云"
            ;;
        4)
            mirror="https://mirror.nju.edu.cn/ubuntu/"
            mirror_name="南京大学"
            ;;
    esac

    # 获取系统代号
    codename=$(lsb_release -cs)
    if [ -z "$codename" ]; then
        red_echo "无法自动检测到系统代号，更换源失败！"
        return 1
    fi
    green_echo "检测到系统代号为: $codename，将更换为$mirror_name源"

    # 备份当前源文件
    green_echo "正在备份当前源文件 /etc/apt/sources.list ..."
    sudo cp /etc/apt/sources.list "/etc/apt/sources.list.bak_$(date +%F-%T)"

    # 写入新源配置
    green_echo "正在写入新的$mirror_name源配置..."
    sudo tee /etc/apt/sources.list > /dev/null <<EOF
deb $mirror ${codename} main restricted universe multiverse
deb $mirror ${codename}-updates main restricted universe multiverse
deb $mirror ${codename}-backports main restricted universe multiverse
deb $mirror ${codename}-security main restricted universe multiverse
deb-src $mirror ${codename} main restricted universe multiverse
deb-src $mirror ${codename}-updates main restricted universe multiverse
deb-src $mirror ${codename}-backports main restricted universe multiverse
deb-src $mirror ${codename}-security main restricted universe multiverse
EOF

    # 刷新软件列表
    green_echo "源文件已更新，正在刷新软件列表 (apt-get update)..."
    sudo apt-get update
    green_echo "$mirror_name软件源更换并刷新完成！"
}

# 检查是否使用国内源（辅助函数）
check_domestic_source() {
    local mirrors=("mirrors.ustc.edu.cn" "mirrors.cloud.tencent.com" "mirrors.aliyun.com" "mirror.nju.edu.cn")
    for mirror in "${mirrors[@]}"; do
        if grep -q "$mirror/ubuntu" /etc/apt/sources.list 2>/dev/null; then
            return 0  # 使用了国内源
        fi
    done
    return 1  # 未使用国内源
}

# 设置系统时区
set_timezone() {
    green_echo "正在设置亚洲/上海时区..."
    sudo timedatectl set-timezone Asia/Shanghai
    sudo timedatectl set-local-rtc 0
    green_echo "时区设置完成。"
}

# 初始化日志系统
init_logging() {
    mkdir -p "$log_dir"
    touch "$log_file"
    chown $REAL_user:$REAL_user "$log_file"
    exec > >(tee -a "$log_file") 2>&1
    echo "=== 安装日志 $(date) ==="
}

# 调试信息
debug_info() {
    echo "====== 系统信息 ====="
    echo "当前用户: $REAL_user"
    echo "用户目录: $home_dir"
    echo "目标目录: $dest_dir"
    echo "日志文件: $log_file"
    echo "内存信息:"
    free -m
    echo "存储信息:"
    df -h
    echo "====================="
}

# 安装系统依赖
install_dependencies() {
    echo "安装系统依赖..."
    sudo apt-get update && \
    sudo apt-get install -y \
        tar \
        gzip \
        wget \
        curl \
        lsof \
        jq \
        unzip
    
    # 检查并安装bc（用于浮点运算）
    if ! command -v bc >/dev/null 2>&1; then
        echo "安装bc工具..."
        sudo apt-get install -y bc
    fi
    
    # 安装i386架构支持
    echo "添加i386架构支持..."
    sudo dpkg --add-architecture i386
    sudo apt-get update
    
    # 安装必要的库
    echo "安装必要的库..."
    sudo apt-get install -y lib32gcc1
    sudo apt-get install -y libcurl4-gnutls-dev:i386
    sudo apt-get install -y screen
    sudo apt-get install -y libc6 libc6:i386  # 替换原glibc，Ubuntu中正确包名
    
    # 添加额外的依赖
    echo "安装额外的依赖..."
    sudo apt-get install -y lib32stdc++6
    sudo apt-get install -y libcurl4-gnutls-dev
    sudo apt-get install -y libgcc1
    sudo apt-get install -y libstdc++6
    sudo apt-get install -y wget
    sudo apt-get install -y ca-certificates
    sudo apt-get install -y screen
    sudo apt-get install -y procps
    sudo apt-get install -y sudo
    
    echo "所有依赖安装完成！"
}

# 创建必要的文件夹
create_necessary_dirs() {
    echo "创建必要的文件夹..."
    mkdir -p ~/.klei/DoNotStarveTogether/MyDediServer
    user_home=$HOME
    mkdir -p $user_home/.klei/DoNotStarveTogether/backup
    mkdir -p $user_home/.klei/DoNotStarveTogether/download_mod
    echo "文件夹创建完成！"
}

# 安装FRP客户端
install_frp_client() {
    echo "====== 安装FRP客户端 ======"
    echo "注意：FRP客户端功能只用于本地服务器，云服务器不需要使用！"
    echo "此功能用于将本地服务器端口口映射到公网，方便外部访问。"
    echo "如果您使用的是云服务器，已经有公网IP，则不需要安装FRP。"
    read -p "确定要安装FRP客户端吗？(y/N): " confirm
    if [[ ! $confirm =~ ^[Yy]$ ]]; then
        echo "取消安装FRP客户端。"
        return 0
    fi

    # 判断是否为root用户
    current_user=$(whoami)
    if [ "$current_user" = "root" ]; then
        frp_dir="/usr/local/frp"  
    else
        frp_dir="/home/$current_user/frp"  
    fi

    # 创建目录并设置权限
    echo "创建FRP目录: $frp_dir"
    sudo mkdir -p $frp_dir
    sudo chmod -R 775 $frp_dir
    cd $frp_dir

    # 下载FRP（兼容root用户目录权限），添加了进度显示
    echo "下载FRP客户端..."
    sudo wget --limit-rate=500k --progress=bar:force -O frp_0.61.1_linux_amd64.tar.gz "http://47.108.31.40:5244/d/myfiles/frp_0.61.1_linux_amd64.tar.gz?sign=4fSsaqh0AACgNld2x26h6i8zDbWQ8Qw5jq6vNMD9IuI=:0"
    sudo tar -xzf frp_0.61.1_linux_amd64.tar.gz
    sudo mv frp_0.61.1_linux_amd64/* $frp_dir/
    sudo rm -rf frp_0.61.1_linux_amd64*

    # 客户端配置
    echo "配置FRP客户端..."
    sudo tee $frp_dir/frpc.toml << EOF
serverAddr = ""
serverPort = 7000
auth.token = ""


EOF

    read -p "请输入FRP服务器IP: " server_ip
    read -p "请输入FRP令牌: " frp_token

    sudo sed -i "s/^serverAddr = \"\"/serverAddr = \"$server_ip\"/" $frp_dir/frpc.toml
    sudo sed -i "s/^auth.token = \"\"/auth.token = \"$frp_token\"/" $frp_dir/frpc.toml

    # 生成systemd服务 - 修复开机自启动问题
    create_systemd_service() {
        local service_type=$1
        # 确定正确的systemd服务目录
        local systemd_dir="/etc/systemd/system/"
        if [ ! -d "$systemd_dir" ]; then
            systemd_dir="/usr/lib/systemd/system/"
        fi
        
        sudo bash -c "cat > ${systemd_dir}frp${service_type}.service << EOF
[Unit]
Description=Frp ${service_type^} Service
After=network.target
Wants=network-online.target
Requires=network-online.target

[Service]
Type=simple
User=root
WorkingDirectory=$frp_dir
ExecStart=$frp_dir/frp${service_type} -c $frp_dir/frp${service_type}.toml
Restart=always
RestartSec=5
StartLimitInterval=60
StartLimitBurst=3

[Install]
WantedBy=multi-user.target
EOF"
        
        # 设置服务文件权限
        sudo chmod 644 ${systemd_dir}frp${service_type}.service
    }

    create_systemd_service c

    # 重载服务并启动，确保开机自启动
    sudo systemctl daemon-reload
    
    # 先尝试停止服务（如果正在运行）
    sudo systemctl stop frpc >/dev/null 2>&1
    
    # 启用并启动服务
    if sudo systemctl enable --now frpc; then
        green_echo "FRP服务已成功设置开机自启动"
    else
        red_echo "设置FRP服务开机自启动失败！"
        return 1
    fi
    
    # 检查服务状态
    if systemctl is-active --quiet frpc; then
        green_echo "FRP服务正在运行"
    else
        yellow_echo "FRP服务未运行，尝试手动启动..."
        if sudo systemctl start frpc && systemctl is-active --quiet frpc; then
            green_echo "FRP服务已手动启动成功"
        else
            red_echo "FRP服务启动失败，请检查配置"
            sudo systemctl status frpc --no-pager
            return 1
        fi
    fi
    
    echo "FRP客户端安装完成！"
}


# FRP自动映射功能完整模块
auto_map_ports() {
    echo "====== FRP自动映射端口 ======"
    echo "注意：此功能只用于本地服务器，云服务器不需要使用！"
    echo "此功能将自动配置FRP客户端映射饥荒服务器端口和面板端口。"

    # 获取当前用户信息
    current_user=$(whoami)
    if [ "$current_user" = "root" ]; then
        frp_base_path="/usr/local/frp"
        klei_base_path="/root/.klei/DoNotStarveTogether"
    else
        frp_base_path="/home/$current_user/frp"
        klei_base_path="/home/$current_user/.klei/DoNotStarveTogether"
    fi

    # 检查FRP是否安装
    if [ ! -f "$frp_base_path/frpc.toml" ]; then
        echo "未找到FRP客户端，请先安装FRP客户端！"
        return 1
    fi

    # 转义特殊字符用于sed命令处理
    escape_special_chars() {
        local str="$1"
        # 转义sed中特殊的字符: / \ &
        echo "$str" | sed -e 's/[\/&]/\\&/g'
    }

    # 确保文件末尾有一个换行符
    ensure_newline_at_eof() {
        local file="$1"
        if [ -f "$file" ]; then
            # 检查文件最后一个字符是否为换行符
            if [ "$(tail -c 1 "$file" | wc -l)" -eq 0 ]; then
                sudo bash -c "echo "" >> '$file'"
            fi
        fi
    }

    # 安全重启FRP服务并检查配置
    safe_restart_frp_with_check() {
        local backup_file="$1"
        echo "尝试重启FRP服务验证配置..."
        
        # 先停止服务
        sudo systemctl stop frpc >/dev/null 2>&1
        
        # 尝试启动服务并检查状态
        if sudo systemctl start frpc; then
            echo "FRP服务已成功重启，配置有效"
            return 0
        else
            red_echo "FRP服务启动失败，配置可能存在问题！"
            echo "错误详情:"
            sudo systemctl status frpc --no-pager | head -n 10
            echo -e "\n建议检查配置文件或运行 'journalctl -xeu frpc.service' 查看详细错误"
            
            # 询问是否还原配置
            if [ -n "$backup_file" ] && [ -f "$backup_file" ]; then
                read -p "是否要还原到修改前的配置？(y/n) " restore_choice
                if [ "$restore_choice" = "y" ] || [ "$restore_choice" = "Y" ]; then
                    sudo cp "$backup_file" "$frp_base_path/frpc.toml"
                    sudo systemctl start frpc
                    echo "已还原到修改前的配置"
                    return 0
                fi
            fi
            return 1
        fi
    }

    # FRP服务管理子菜单
    frp_management() {
        while true; do
            echo -e "\n====== FRP服务管理 ======"
            echo "1) 启动frpc服务"
            echo "2) 停止frpc服务"
            echo "3) 重启frpc服务"
            echo "4) 查看frpc状态"
            echo "0) 返回主菜单"
            read -p "请输入操作编号: " manage_choice

            case $manage_choice in
                1)
                    echo "启动FRP客户端..."
                    if sudo systemctl start frpc; then
                        echo "FRP客户端已成功启动"
                    else
                        echo "FRP客户端启动失败"
                        sudo systemctl status frpc --no-pager | head -n 10
                    fi
                    ;;
                2)
                    echo "停止FRP客户端..."
                    if sudo systemctl stop frpc; then
                        echo "FRP客户端已成功停止"
                    else
                        echo "FRP客户端停止失败"
                    fi
                    ;;
                3)
                    echo "尝试重启FRP服务..."
                    if sudo systemctl restart frpc; then
                        echo "FRP服务已成功重启"
                    else
                        red_echo "FRP服务重启失败！"
                        echo "错误详情:"
                        sudo systemctl status frpc --no-pager | head -n 10
                    fi
                    ;;
                4)
                    echo "查看FRP客户端状态:"
                    sudo systemctl status frpc
                    ;;
                0)
                    echo "返回主菜单"
                    return 0
                    ;;
                *)
                    echo "无效选项，请重新输入"
                    ;;
            esac
        done
    }

    # 处理单个存档的端口映射
    process_selected_cluster() {
        local selected_index=$1
        local cluster_dirs=("${!2}")
        local cluster_names=("${!3}")
        
        # 获取选定存档信息
        selected_dir="${cluster_dirs[$selected_index]}"
        cluster_name="${cluster_names[$selected_index]}"
        
        # 解析server.ini文件获取端口
        declare -A ports
        for server_dir in "$selected_dir"/*/; do
            config_file="${server_dir}server.ini"
            if [ -f "$config_file" ]; then
                port=$(grep -oP 'server_port\s*=\s*\K\d+' "$config_file" | head -1)
                if [[ -n "$port" ]]; then
                    ports["$port"]=1
                fi
            fi
        done
        
        if [ ${#ports[@]} -eq 0 ]; then
            red_echo "警告：未在存档 '$cluster_name' 中找到端口信息！"
            return 1
        fi
        
        # 更新FRP配置
        safe_cluster_name=$(echo "$cluster_name" | sed 's/["]/_/g' | sed 's/[\/]/_/g')
        
        # 确保文件末尾有换行
        ensure_newline_at_eof "$frp_base_path/frpc.toml"
        
        for port in "${!ports[@]}"; do
            proxy_name="饥荒_${safe_cluster_name}_${port}"
            # 先删除已存在的配置
            escaped_name=$(escape_special_chars "$proxy_name")
            sudo sed -i '/^\[\[proxies\]\]/,/^\[\[proxies\]\]/ { /name = "'"$escaped_name"'"/ { :a; /^\[\[proxies\]\]/! { N; ba; }; d; }; }' "$frp_base_path/frpc.toml"
            sudo sed -i '/^\[\[proxies\]\]/,$ { /name = "'"$escaped_name"'"/ { :a; $! { N; ba; }; d; }; }' "$frp_base_path/frpc.toml"
            
            # 添加新配置
            proxy_config="[[proxies]]
name = \"$proxy_name\"
type = \"udp\"
localIP = \"127.0.0.1\"
localPort = $port
remotePort = $port
"
            # 确保文件末尾有换行
            ensure_newline_at_eof "$frp_base_path/frpc.toml"
            
            # 添加新配置
            echo "$proxy_config" | sudo tee -a "$frp_base_path/frpc.toml" > /dev/null
        done
        
        echo "已添加存档 '$cluster_name' 的端口映射: ${!ports[@]}"
        return 0
    }

    # 显示主选项菜单
    while true; do
        echo -e "\n请选择操作："
        echo "1) 面板端口自动映射"
        echo "2) 游戏存档自动添加"
        echo "3) 删除端口映射"
        echo "4) 还原frpc.toml"
        echo "5) FRP服务管理"
        echo "0) 退出"
        read -p "请输入选项: " choice

        case $choice in
            1)  # 面板端口自动映射
                echo -e "\n====== 面板端口自动映射 ======"
                
                # 读取config.yml文件
                config_yml="$dest_dir/config.yml"
                if [ -f "$config_yml" ]; then
                    echo "找到配置文件: $config_yml"
                    local_port=$(grep -oP 'port\s*=\s*\K\d+' "$config_yml" | head -1)
                    if [ -n "$local_port" ]; then
                        echo "从配置文件读取到本地端口: $local_port"
                    fi
                else
                    echo "未找到config.yml文件，使用默认端口"
                fi
                
                # 确认本地端口
                default_local_port=${local_port:-8082}
                read -p "请输入本地端口 [默认: $default_local_port]: " input_local_port
                local_port=${input_local_port:-$default_local_port}
                
                # 确认外网端口
                default_remote_port=18082
                read -p "请输入外网端口 [默认: $default_remote_port]: " input_remote_port
                remote_port=${input_remote_port:-$default_remote_port}
                
                # 备份当前配置
                backup_file="$frp_base_path/frpc.toml.bak_$(date +%Y%m%d%H%M%S)"
                sudo cp "$frp_base_path/frpc.toml" "$backup_file"
                
                # 添加面板配置
                panel_config="[[proxies]]
name = \"饥荒面板\"
type = \"tcp\"
localIP = \"127.0.0.1\"
localPort = $local_port
remotePort = $remote_port
"
                # 先删除已存在的配置
                escaped_name=$(escape_special_chars "饥荒面板")
                sudo sed -i '/^\[\[proxies\]\]/,/^\[\[proxies\]\]/ { /name = "'"$escaped_name"'"/ { :a; /^\[\[proxies\]\]/! { N; ba; }; d; }; }' "$frp_base_path/frpc.toml"
                sudo sed -i '/^\[\[proxies\]\]/,$ { /name = "'"$escaped_name"'"/ { :a; $! { N; ba; }; d; }; }' "$frp_base_path/frpc.toml"
                
                # 确保文件末尾有换行
                ensure_newline_at_eof "$frp_base_path/frpc.toml"
                
                # 添加新配置
                echo "$panel_config" | sudo tee -a "$frp_base_path/frpc.toml" > /dev/null
                
                # 通过重启服务验证配置
                safe_restart_frp_with_check "$backup_file"
                
                echo "面板端口映射配置操作完成！"
                echo "本地端口: $local_port -> 外网端口: $remote_port"
                ;;
                
            2)  # 游戏存档自动添加（支持多选和全部）
                echo -e "\n====== 游戏存档自动添加 ======"
                
                # 初始化存档根目录变量
                storage_root=""
                
                # 尝试从dst_config文件获取存档路径
                dst_config="$dest_dir/dst_config"
                if [ -f "$dst_config" ]; then
                    echo "找到配置文件: $dst_config"
                    storage_root=$(grep -oP 'persistent_storage_root\s*=\s*\K.*' "$dst_config" | head -1)
                    
                    if [ -n "$storage_root" ]; then
                        echo "从配置文件读取到存档目录: $storage_root"
                    else
                        echo "dst_config文件中未找到persistent_storage_root，将使用默认路径"
                        storage_root="$klei_base_path"
                    fi
                else
                    echo "未找到dst_config文件，将使用默认路径"
                    storage_root="$klei_base_path"
                fi
                
                # 验证存档目录是否存在
                if [ ! -d "$storage_root" ]; then
                    red_echo "存档目录不存在: $storage_root"
                    continue
                fi
                echo "使用存档目录: $storage_root"
                
                # 寻找存档目录下的cluster.ini文件
                cluster_dirs=()
                cluster_names=()
                
                # 查找一级目录
                while IFS= read -r -d $'\0' dir; do
                    if [ -f "$dir/cluster.ini" ]; then
                        cluster_dirs+=("$dir")
                        name=$(grep -oP 'cluster_name\s*=\s*\K.*' "$dir/cluster.ini" | head -1)
                        clean_name=$(echo "$name" | tr -d '\n' | sed 's/[[:space:]]\+$//')
                        cluster_names+=("${clean_name:-未命名}")
                    fi
                done < <(find "$storage_root" -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null)
                
                # 如果未找到，查找下一级目录
                if [ ${#cluster_dirs[@]} -eq 0 ]; then
                    echo "在一级目录未找到存档，搜索二级目录..."
                    while IFS= read -r -d $'\0' dir; do
                        if [ -f "$dir/cluster.ini" ]; then
                            cluster_dirs+=("$dir")
                            name=$(grep -oP 'cluster_name\s*=\s*\K.*' "$dir/cluster.ini" | head -1)
                            clean_name=$(echo "$name" | tr -d '\n' | sed 's/[[:space:]]\+$//')
                            cluster_names+=("${clean_name:-未命名}")
                        fi
                    done < <(find "$storage_root" -mindepth 2 -maxdepth 2 -type d -print0 2>/dev/null)
                fi
                
                # 检查是否找到存档
                if [ ${#cluster_dirs[@]} -eq 0 ]; then
                    red_echo "未在 $storage_root 目录下找到任何包含cluster.ini的存档目录"
                    continue
                fi
                
                # 显示存档选项
                echo -e "\n找到以下存档:"
                for i in "${!cluster_dirs[@]}"; do
                    dir_name=$(basename "${cluster_dirs[$i]}")
                    printf "%d) %s - %s\n" "$((i+1))" "$dir_name" "${cluster_names[$i]}"
                done
                
                # 选择存档（支持多选和全部）
                read -p "请选择要添加映射的存档编号 [1-${#cluster_dirs[@]}，可输入多个编号用空格分隔，或输入all选择全部]: " selected
                
                # 处理全部选择
                local selected_indices=()
                local valid_selection=1
                
                if [ "$selected" = "all" ] || [ "$selected" = "ALL" ]; then
                    # 选择所有存档
                    for ((i=0; i<${#cluster_dirs[@]}; i++)); do
                        selected_indices+=($i)
                    done
                else
                    # 验证输入格式
                    if [[ ! "$selected" =~ ^[0-9]+( [0-9]+)*$ ]]; then
                        red_echo "无效的选择格式！请输入数字，多个编号用空格分隔，或输入all选择全部"
                        continue
                    fi
                    
                    # 分割选择的编号并验证范围
                    for num in $selected; do
                        if [[ ! "$num" =~ ^[0-9]+$ ]] || [ "$num" -lt 1 ] || [ "$num" -gt ${#cluster_dirs[@]} ]; then
                            red_echo "无效的选择: $num"
                            valid_selection=0
                            break
                        fi
                        # 转换为数组索引（减1）
                        selected_indices+=($((num-1)))
                    done
                fi
                
                if [ $valid_selection -eq 0 ]; then
                    continue
                fi
                
                # 备份当前配置
                backup_file="$frp_base_path/frpc.toml.bak_$(date +%Y%m%d%H%M%S)"
                sudo cp "$frp_base_path/frpc.toml" "$backup_file"
                
                # 处理每个选中的存档
                echo -e "\n开始添加选中的存档映射..."
                local success=0
                for index in "${selected_indices[@]}"; do
                    process_selected_cluster "$index" cluster_dirs[@] cluster_names[@]
                    if [ $? -eq 0 ]; then
                        success=1
                    fi
                done
                
                if [ $success -eq 1 ]; then
                    # 通过重启服务验证配置
                    safe_restart_frp_with_check "$backup_file"
                    echo -e "\n所有选中的存档端口映射已添加完成！"
                else
                    red_echo "\n未成功添加任何存档映射"
                fi
                ;;
                
            3)  # 删除端口映射（支持多选和全部）
                echo -e "\n====== 删除端口映射 ======"
                
                # 备份当前配置
                backup_file="$frp_base_path/frpc.toml.bak_$(date +%Y%m%d%H%M%S)"
                sudo cp "$frp_base_path/frpc.toml" "$backup_file"
                echo "已创建配置备份: $(basename "$backup_file")"
                
                # 列出所有代理配置
                echo "当前端口映射列表:"
                proxies=()
                while IFS= read -r line; do
                    if [[ $line =~ name\ =\ \"(.*)\" ]]; then
                        clean_name=$(echo "${BASH_REMATCH[1]}" | tr -d '\n')
                        proxies+=("$clean_name")
                    fi
                done < "$frp_base_path/frpc.toml"
                
                if [ ${#proxies[@]} -eq 0 ]; then
                    echo "未找到任何端口映射配置"
                    continue
                fi
                
                # 显示代理选项
                for i in "${!proxies[@]}"; do
                    printf "%d) %s\n" "$((i+1))" "${proxies[$i]}"
                done
                
                # 选择要删除的代理（支持多选和全部）
                read -p "请选择要删除的映射编号 [1-${#proxies[@]}，可输入多个编号用空格分隔，或输入all选择全部，0取消]: " selected
                
                if [ "$selected" = "0" ]; then
                    echo "已取消删除操作"
                    continue
                fi
                
                # 处理全部选择
                local selected_indices=()
                local valid_selection=1
                
                if [ "$selected" = "all" ] || [ "$selected" = "ALL" ]; then
                    # 选择所有映射
                    for ((i=0; i<${#proxies[@]}; i++)); do
                        selected_indices+=($i)
                    done
                else
                    # 验证输入格式
                    if [[ ! "$selected" =~ ^[0-9]+( [0-9]+)*$ ]]; then
                        red_echo "无效的选择格式！请输入数字，多个编号用空格分隔，或输入all选择全部，0取消"
                        continue
                    fi
                    
                    # 分割选择的编号并验证范围
                    for num in $selected; do
                        if [[ ! "$num" =~ ^[0-9]+$ ]] || [ "$num" -lt 1 ] || [ "$num" -gt ${#proxies[@]} ]; then
                            red_echo "无效的选择: $num"
                            valid_selection=0
                            break
                        fi
                        # 转换为数组索引（减1）
                        selected_indices+=($((num-1)))
                    done
                fi
                
                if [ $valid_selection -eq 0 ]; then
                    continue
                fi
                
                # 处理每个选中的代理配置
                echo -e "\n开始删除选中的端口映射..."
                local temp_file=$(mktemp)
                local in_block=0
                local current_block=""
                local delete_block=0
                
                # 先复制所有内容到临时文件，标记需要删除的块
                while IFS= read -r line; do
                    if [[ "$line" == "[[proxies]]" ]]; then
                        in_block=1
                        current_block="$line"$'\n'
                        delete_block=0
                    elif [[ $in_block -eq 1 ]]; then
                        current_block+="$line"$'\n'
                        
                        # 检查当前块是否是要删除的
                        if [[ "$line" =~ name\ =\ \"(.*)\" ]]; then
                            current_name="${BASH_REMATCH[1]}"
                            
                            # 检查当前名称是否在选中的列表中
                            for index in "${selected_indices[@]}"; do
                                target_name="${proxies[$index]}"
                                if [ "$current_name" = "$target_name" ]; then
                                    delete_block=1
                                    break
                                fi
                            done
                        fi
                        
                        # 配置块结束条件
                        if [[ -z "$line" || "$(echo "$line" | trim)" == "[[proxies]]" ]]; then
                            in_block=0
                            if [[ $delete_block -eq 0 ]]; then
                                echo -n "$current_block" >> "$temp_file"
                            else
                                echo "已删除: $current_name"
                            fi
                            current_block=""
                        fi
                    else
                        echo "$line" >> "$temp_file"
                    fi
                done < "$frp_base_path/frpc.toml"
                
                # 处理最后一个配置块
                if [[ $in_block -eq 1 && $delete_block -eq 0 ]]; then
                    echo -n "$current_block" >> "$temp_file"
                fi
                
                # 将临时文件内容写回原文件
                sudo cp "$temp_file" "$frp_base_path/frpc.toml"
                rm -f "$temp_file"
                
                # 通过重启服务验证配置
                safe_restart_frp_with_check "$backup_file"
                echo -e "\n所有选中的端口映射已删除完成！"
                ;;
                
            4)  # 还原frpc.toml
                echo -e "\n====== 还原frpc.toml ======"
                
                latest_backup=$(ls -t "$frp_base_path"/frpc.toml.bak_* 2>/dev/null | head -1)
                if [ -z "$latest_backup" ]; then
                    red_echo "未找到任何备份文件！"
                    continue
                fi
                
                echo "找到最新备份: $(basename "$latest_backup")"
                read -p "确定要还原到此备份吗？(y/n) " confirm
                if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
                    # 先备份当前配置
                    sudo cp "$frp_base_path/frpc.toml" "$frp_base_path/frpc.toml.bak_before_restore_$(date +%Y%m%d%H%M%S)"
                    # 还原备份
                    sudo cp "$latest_backup" "$frp_base_path/frpc.toml"
                    
                    # 尝试重启服务
                    if sudo systemctl restart frpc; then
                        echo "frpc.toml已成功还原并重启服务！"
                    else
                        echo "frpc.toml已还原，但服务重启失败"
                        sudo systemctl status frpc --no-pager | head -n 10
                    fi
                else
                    echo "已取消还原操作"
                fi
                ;;
                
            5)  # FRP服务管理
                frp_management
                ;;
                
            0)  # 退出
                echo "退出FRP自动映射功能"
                return 0
                ;;
                
            *)  # 无效选项
                red_echo "无效的选项，请重新输入！"
                ;;
        esac
    done
}

# 辅助函数：去除字符串前后空格
trim() {
    local var="$*"
    var="${var#"${var%%[![:space:]]*}"}"
    var="${var%"${var##*[![:space:]]}"}"
    echo -n "$var"
}

# 辅助函数：红色输出
red_echo() {
    echo -e "\033[0;31m$1\033[0m"
}

# 面板服务管理
manage_panel_service() {
    if ! check_panel_exist; then
        red_echo "未检测到面板安装，请先安装面板！"
        return 1
    fi

    clear
    echo "============================================="
    echo "          饥荒面板服务管理"
    echo "============================================="
    echo "1. 启动饥荒面板"
    echo "2. 停止饥荒面板"
    echo "3. 重启饥荒面板"
    echo "4. 查看面板状态"
    echo "0. 返回主菜单"
    echo "============================================="
    read -p "请输入操作编号: " choice

    case $choice in
        1)
            echo "启动饥荒面板服务..."
            sudo systemctl start dst-admin-go
            if [ $? -eq 0 ]; then
                green_echo "面板启动成功！访问地址: http://$(curl -s icanhazip.com):8082"
            else
                red_echo "面板启动失败！"
            fi
            ;;
        2)
            echo "停止饥荒面板服务..."
            sudo systemctl stop dst-admin-go
            if [ $? -eq 0 ]; then
                green_echo "面板已成功停止"
            else
                red_echo "面板停止失败！"
            fi
            ;;
        3)
            echo "重启饥荒面板服务..."
            sudo systemctl restart dst-admin-go
            if [ $? -eq 0 ]; then
                green_echo "面板重启成功！访问地址: http://$(curl -s icanhazip.com):8082"
            else
                red_echo "面板重启失败！"
            fi
            ;;
        4)
            echo "查看饥荒面板服务状态..."
            sudo systemctl status dst-admin-go
            ;;
        0)
            return 0
            ;;
        *)
            echo "无效的选择，请重新输入！"
            ;;
    esac
    read -p "按回车键返回服务管理菜单..."
    manage_panel_service
}


# 服务器性能测试 
run_benchmark() {
    echo "====== 开始服务器性能测试 ======"
    
    # 创建目录
    mkdir -p "$bench_dir" || {
        echo "无法创建测试目录: $bench_dir"
        exit 1
    }

    # 检查是否存在之前的跑分结果文件
    benchmark_page="$bench_dir/benchmark_page.txt"
    benchmark_log="$bench_dir/benchmark_analysis.log"
    raw_output=""
    
    # 增强的用户选择逻辑
    if [ -f "$benchmark_page" ]; then
        echo "检测到已存在跑分结果文件: $benchmark_page"
        echo "请选择操作："
        echo "1) 解析现有结果文件"
        echo "2) 重新进行跑分测试"
        read -p "请输入选项 (1-2): " choice
        
        case $choice in
            1)
                echo "使用现有结果文件进行分析..."
                ;;
            2)
                echo "将重新进行跑分测试..."
                raw_output="need_to_run"
                ;;
            *)
                red_echo "无效选择，默认使用现有结果文件"
                ;;
        esac
    else
        raw_output="need_to_run"
        echo "未检测到现有跑分结果文件，将进行新的测试"
    fi

    # 如果需要重新跑分或结果文件不存在，则执行测试
    if [ -n "$raw_output" ] || [ ! -f "$benchmark_page" ]; then
        # 检测是否已存在可执行文件
        if [ -f "$bench_dir/geekbench5" ]; then
            echo "检测到已安装的Geekbench，跳过下载安装..."
        else
            # 系统架构检测
            arch=$(uname -m)
            case $arch in
                x86_64)
                    gb_url="http://47.108.31.40:5244/d/myfiles/Geekbench-5.4.5-Linux.tar.gz?sign=622NhrH1jYbXdiBN_Uy4qEqlh71Cp63ItXxGByXuPbE=:0"
                    ;;
                *)
                    echo "不支持的架构: $arch"
                    exit 1
                    ;;
            esac

            # 下载Geekbench - 添加限速500kb/s
            echo "正在下载Geekbench..."
            if ! wget --limit-rate=500k --progress=bar:force -P "$bench_dir" "$gb_url"; then
                echo "下载失败！请检查："
                echo "1. 网络连接状态"
                echo "2. 磁盘空间是否充足"
                exit 1
            fi

            # 解压文件
            echo "正在解压安装包..."
            if ! tar -xzf "$bench_dir/$(basename $gb_url)" -C "$bench_dir" --strip-components=1; then
                echo "解压失败！可能原因："
                echo "1. 下载文件不完整"
                echo "2. 磁盘空间不足"
                rm -f "$bench_dir/$(basename $gb_url)"
                exit 1
            fi

            # 清理安装包
            rm -f "$bench_dir/$(basename $gb_url)"
        fi

        # 安装依赖
        echo "检查系统依赖..."
        if ! dpkg -l | grep -q libcurl4; then
            sudo apt-get install -y libcurl4 >/dev/null 2>&1
        fi
        if ! dpkg -l | grep -q libncurses5; then
            sudo apt-get install -y libncurses5 >/dev/null 2>&1
        fi

        # 运行测试
        echo "开始性能测试(大约需要5-10分钟)..."
        raw_output=$("$bench_dir/geekbench5" --upload 2>&1)
        echo "$raw_output" | tee "$bench_dir/benchmark_result.txt"

        # 提取结果URL
        echo "正在获取测试结果链接..."
        url=$(grep -oE 'https?://[a-zA-Z0-9./?=_-]+' <<< "$raw_output" | grep 'browser.geekbench' | head -1)

        if [ -n "$url" ]; then
            echo "正在下载结果页面..."
            wget --quiet --content-on-error --output-document="$benchmark_page" "$url"
        fi
    else
        # 使用现有文件时尝试从文件中提取URL
        url=$(grep -oE 'https?://[a-zA-Z0-9./?=_-]+' "$bench_dir/benchmark_result.txt" | grep 'browser.geekbench' | head -1)
    fi

    # 初始化解析日志
    echo "=== 性能测试解析日志 - $(date) ===" > "$benchmark_log"
    echo "解析目标文件: $benchmark_page" >> "$benchmark_log"
    echo "原始输出文件: $bench_dir/benchmark_result.txt" >> "$benchmark_log"
    echo "====================================" >> "$benchmark_log"

    if [ -f "$benchmark_page" ]; then
        echo "========================================"
        echo "测试完成！正在解析详细结果..."
        echo "========================================"
        
        # 获取CPU核心数
        cpu_cores=$(nproc)
        echo "检测到CPU核心数: $cpu_cores" >> "$benchmark_log"
        
        # 修复解析逻辑
        if ! grep -q "<!DOCTYPE html>" "$benchmark_page" 2>/dev/null; then
            red_echo "错误：获取的不是有效的HTML结果页面"
            echo "错误：获取的不是有效的HTML结果页面" >> "$benchmark_log"
            cat "$benchmark_page" >> "$benchmark_log" 2>/dev/null
        fi
        
        # 提取系统信息和跑分数据
        echo "尝试多种方式提取系统信息和跑分数据..." >> "$benchmark_log"
        
        # 改进的跑分数据提取逻辑 - 搜索115-130行范围
        echo "正在从115-130行范围提取跑分数据..." >> "$benchmark_log"
        
        # 提取115-130行的所有数字
        scores_section=$(sed -n '115,130p' "$benchmark_page")
        echo "提取的跑分数据区域内容：" >> "$benchmark_log"
        echo "$scores_section" >> "$benchmark_log"
        
        # 提取所有数字并排序
        all_scores=$(echo "$scores_section" | grep -oE '[0-9]+' | sort -n)
        echo "提取的所有数字: $all_scores" >> "$benchmark_log"
        
        # 提取有效分数（大于100的数字）
        valid_scores=$(echo "$all_scores" | awk '$1 > 100')
        echo "有效分数: $valid_scores" >> "$benchmark_log"
        
        # 计算有效分数数量
        score_count=$(echo "$valid_scores" | wc -l)
        echo "有效分数数量: $score_count" >> "$benchmark_log"
        
        # 根据分数数量确定单核和多核分数
        if [ "$score_count" -ge 2 ]; then
            # 有两个以上有效分数，取最小和最大
            single_core_num=$(echo "$valid_scores" | head -1)
            multi_core_num=$(echo "$valid_scores" | tail -1)
            single_core="$single_core_num"
            multi_core="$multi_core_num"
            echo "确定单核分数: $single_core, 多核分数: $multi_core" >> "$benchmark_log"
        elif [ "$score_count" -eq 1 ]; then
            # 只有一个有效分数
            single_core_num=$(echo "$valid_scores")
            single_core="$single_core_num"
            multi_core="未知"
            echo "只有一个有效分数，设为单核分数: $single_core" >> "$benchmark_log"
        else
            # 没有有效分数，尝试备用方法
            red_echo "警告：无法从标准位置提取跑分数据，尝试备用方法..."
            echo "警告：无法从标准位置提取跑分数据，尝试备用方法..." >> "$benchmark_log"
            
            # 备用方法：在整个文件中搜索常见的跑分模式
            backup_scores=$(grep -oE '>[0-9]{3,5}<' "$benchmark_page" | grep -oE '[0-9]+' | sort -n | uniq)
            echo "备用方法找到的分数: $backup_scores" >> "$benchmark_log"
            
            backup_count=$(echo "$backup_scores" | wc -l)
            if [ "$backup_count" -ge 2 ]; then
                single_core_num=$(echo "$backup_scores" | head -1)
                multi_core_num=$(echo "$backup_scores" | tail -1)
                single_core="$single_core_num"
                multi_core="$multi_core_num"
                echo "备用方法确定单核: $single_core, 多核: $multi_core" >> "$benchmark_log"
            else
                single_core="未知"
                multi_core="未知"
                red_echo "无法提取跑分数据，请手动查看结果页面"
                echo "无法提取跑分数据" >> "$benchmark_log"
            fi
        fi
        
        # 提取系统信息
        os_version=$(grep -oP '<td class="system-value"[^>]*>\K[^<]+' "$benchmark_page" | grep -i 'ubuntu' | head -1)
        if [ -z "$os_version" ]; then
            os_version=$(lsb_release -d | cut -f2)
        fi
        
        cpu_model=$(grep -oP '<td class="system-value"[^>]*><a[^>]+>\K[^<]+' "$benchmark_page" | grep -i 'cpu\|processor' | head -1)
        if [ -z "$cpu_model" ]; then
            cpu_model=$(grep -m1 'model name' /proc/cpuinfo | cut -d: -f2 | sed -e 's/^ *//')
        fi
        
        cores=$(grep -oP '<td class="system-value"[^>]*>\K\d+ Cores' "$benchmark_page" | head -1)
        if [ -z "$cores" ]; then
            cores="${cpu_cores} Cores"
        fi
        
        frequency=$(grep -oP '<td class="system-value"[^>]*>\K[\d.]+ GHz' "$benchmark_page" | head -1)
        if [ -z "$frequency" ]; then
            frequency=$(grep -m1 'cpu MHz' /proc/cpuinfo | cut -d: -f2 | sed -e 's/^ *//' | awk '{printf "%.2f GHz", $1/1000}')
        fi
        
        memory=$(grep -oP '<td class="system-value"[^>]*>\K[\d.]+ [GM]B' "$benchmark_page" | grep -i 'memory' | head -1)
        if [ -z "$memory" ]; then
            memory=$(free -h | awk '/Mem:/ {print $2}')
        fi
        
        # 将解析结果写入日志
        echo -e "\n【系统信息解析结果】" >> "$benchmark_log"
        echo "操作系统: ${os_version:-未知}" >> "$benchmark_log"
        echo "CPU型号: ${cpu_model:-未知}" >> "$benchmark_log"
        echo "核心数: ${cores:-未知}" >> "$benchmark_log"
        echo "CPU频率: ${frequency:-未知}" >> "$benchmark_log"
        echo "内存大小: ${memory:-未知}" >> "$benchmark_log"
        echo "单核心跑分: ${single_core:-未知}" >> "$benchmark_log"
        echo "多核心跑分: ${multi_core:-未知}" >> "$benchmark_log"
        
        # 显示解析结果
        echo -e "\n【系统信息】"
        echo "操作系统: ${os_version:-未知}"
        echo "CPU型号: ${cpu_model:-未知}"
        echo "核心数: ${cores:-未知}"
        echo "CPU频率: ${frequency:-未知}"
        echo "内存大小: ${memory:-未知}"
        
        echo -e "\n【性能测试结果】"
        echo "单核心跑分: ${single_core:-未知}"
        echo "多核心跑分: ${multi_core:-未知}"
        
        # 新增：云服务器CPU性能对比
        echo -e "\n【云服务器CPU性能对比参考】"
        if [ "$cpu_cores" -eq 2 ]; then
            echo "=== 2核配置性能对比（按多核得分排序）==="
            echo "雨云 i9-13900KF(2核): 单核1878 | 多核3341"
            echo "华为云 Xeon Gold 6146: 单核1074 | 多核2085"  
            echo "Ucloud EPYC: 单核973 | 多核1851"
            echo "火山引擎 EPYC 9Y24: 单核1521 | 多核1949"
            echo "腾讯云轻量 EPYC 7K62: 单核1006 | 多核1741"
            echo "您的服务器: 单核${single_core:-未知} | 多核${multi_core:-未知}"
        else
            echo "=== 4核配置性能对比（按多核得分排序）==="
            echo "华为云 X实例 4核8G: 单核1219 | 多核4564"
            echo "华为云 S7 4核8G: 单核1167 | 多核4392"
            echo "雨云 i9-13900KF(4核): 单核1534 | 多核4031"
            echo "华为云 C3 Xeon Gold: 单核914 | 多核3422"
            echo "腾讯云轻量 4核8G: 单核891 | 多核3034"
            echo "华为云 C7 关超线程: 单核1251 | 多核2400"
            echo "您的服务器: 单核${single_core:-未知} | 多核${multi_core:-未知}"
        fi
        
        # 增强饥荒服务器适用性评估
        if [ -n "$single_core_num" ]; then
            echo -e "\n【饥荒服务器适用性评估】"
            if [ "$single_core_num" -lt 800 ]; then
                red_echo "当前服务器单核性能较低（${single_core_num}分 < 800分）"
                yellow_echo "建议配置："
                yellow_echo "- 最多支持3-4名玩家"
                yellow_echo "- 少量使用MOD，避免大型MOD"
                yellow_echo "- 定期清理游戏世界，建议开小一点的世界"
                yellow_echo "- 生物太多可能会卡，建议控制生物数量"
                echo "评估结果: 单核性能较低（${single_core_num}分），最多支持3-4名玩家" >> "$benchmark_log"
                
            elif [ "$single_core_num" -lt 1100 ]; then
                yellow_echo "当前服务器单核性能中等（${single_core_num}分 = 800-1100分）"
                green_echo "建议配置："
                green_echo "- 可支持5-6名玩家"  
                green_echo "- 可以使用中等规模的MOD组合和少量大型MOD"
                green_echo "- 适合中小型服务器"
                echo "评估结果: 单核性能中等（${single_core_num}分），可支持5-6名玩家" >> "$benchmark_log"
                
            elif [ "$single_core_num" -lt 1400 ]; then
                green_echo "当前服务器单核性能良好（${single_core_num}分 = 1100-1400分）"
                green_echo "建议配置："
                green_echo "- 可支持6-8名玩家"
                green_echo "- 能够流畅运行大多数MOD组合"
                green_echo "- 适合长期建家服务器，能够流畅体验游戏"
                echo "评估结果: 单核性能良好（${single_core_num}分），可支持6-8名玩家" >> "$benchmark_log"
                
            elif [ "$single_core_num" -lt 1800 ]; then
                green_echo "当前服务器单核性能优秀（${single_core_num}分 = 1400-1800分）"
                green_echo "建议配置："
                green_echo "- 可支持8-10名玩家"
                green_echo "- 能够流畅运行大多数MOD组合"
                green_echo "- 适合长期建家服务器，能够流畅运行游戏"
                echo "评估结果: 单核性能优秀（${single_core_num}分），可支持8-10名玩家" >> "$benchmark_log"
                
            else
                green_echo "当前服务器单核性能极佳（${single_core_num}分 > 1800分）"
                green_echo "建议配置："
                green_echo "- 可支持10名以上玩家"
                green_echo "- 能够流畅运行大多数MOD组合"
                green_echo "- 适合大型长期建家服务器"
                echo "评估结果: 单核性能极佳（${single_core_num}分），可支持10名以上玩家" >> "$benchmark_log"
            fi
        else
            yellow_echo "无法解析跑分数值，无法提供性能评估"
            echo "评估结果: 无法解析跑分数值" >> "$benchmark_log"
        fi
        
        # 多核性能建议（针对4核及以上）
        if [ "$cpu_cores" -ge 4 ]; then
            echo -e "\n【多核优化建议】"
            green_echo "检测到您的服务器有 ${cpu_cores} 个核心，推荐配置："
            green_echo "- 可以开启多层服务器，合理分配核心资源"
            green_echo "- 每个游戏世界分配1个核心，合理分配玩家"
            green_echo "- 能够支持更多的玩家同时在线"
            echo "多核建议: ${cpu_cores}核心，推荐开启多层服务器" >> "$benchmark_log"
        fi
        
        # 新增：带宽建议（固定提示，不依赖测试结果）
        echo -e "\n【网络带宽建议】"
        yellow_echo "重要提示：带宽与玩家数量关系（不依赖测试结果）："
        yellow_echo "- 平均上传1M带宽可以支持4名玩家"
        yellow_echo "- 换算上传速度就是128KB/s可以带4个人"
        yellow_echo "- 请根据预期玩家数量配置相应带宽"
        
        # 新增：综合优化建议
        echo -e "\n【综合优化建议】"
        if [ "$cpu_cores" -ge 4 ]; then
            green_echo "✓ 推荐开启多层服务器，充分利用多核性能"
        else
            yellow_echo "● 考虑升级到4核以上配置以获得更好体验"
        fi
        
        if [ -n "$single_core_num" ] && [ "$single_core_num" -lt 1100 ]; then
            yellow_echo "● 建议控制MOD数量，避免性能消耗大的MOD"
            yellow_echo "● 定期清理无用实体，优化游戏世界"
        fi
        
        green_echo "✓ 确保有足够的虚拟内存（脚本已自动配置）"
        green_echo "✓ 定期备份存档，防止数据丢失"
        
        # 仅保留参考信息部分
        echo -e "\n【参考信息】"
        echo "服务器参考跑分：单核1100分左右可流畅支持6人游戏"
        echo "腾讯云轻量单核参考跑分：800分左右，可流畅运行纯净或小mod服务器"
        echo "华为云参考跑分：1200分左右，可流畅运行长期建家或大型mod服务器"
        echo "性能测试仅供参考，服务器实际表现以实际使用为准"
        
        echo -e "\n========================================"
        if [ -n "$url" ]; then
            echo "完整测试结果请访问："
            echo "$url"
            echo "完整测试结果URL: $url" >> "$benchmark_log"
        fi
        echo "更多跑分数据参考: https://browser.geekbench.com/user/463719"
        echo "========================================"
        echo "解析日志已保存至: $benchmark_log"
        
        # 新增调试信息
        if [ "$single_core" = "未知" ] || [ "$multi_core" = "未知" ]; then
            yellow_echo "提示：如果跑分数据显示为'未知'，您可以："
            yellow_echo "1. 手动访问上面的URL查看详细结果"
            yellow_echo "2. 检查 $benchmark_log 文件了解详细解析过程"
            yellow_echo "3. 重新运行测试获取最新结果"
        fi
    else
        echo "未能获取测试结果文件，请检查："
        echo "1. 使用vi查看原始输出: vi $bench_dir/benchmark_result.txt"
        echo "2. 尝试重新运行测试"
        echo "3. 确保服务器能访问geekbench.com"
        echo "最后10行输出："
        tail -n 10 "$bench_dir/benchmark_result.txt"
        
        # 记录错误信息到日志
        echo "错误：未能获取测试结果文件" >> "$benchmark_log"
        echo "最后10行原始输出：" >> "$benchmark_log"
        tail -n 10 "$bench_dir/benchmark_result.txt" >> "$benchmark_log"
        
        exit 1
    fi
}

# 增强检测函数
check_panel_exist() {
    local check_targets=(
        "$dest_dir/dst-admin-go"
        "$dest_dir/version.txt"
        "$dest_dir/dist/index.html"
        "$dest_dir/static"
    )

    for target in "${check_targets[@]}"; do
        if [ -e "$target" ]; then
            echo "检测到面板文件: $target"
            return 0
        fi
    done
    return 1
}

# 检查饥荒服务器是否已安装
check_dst_server_exist() {
    if [ -d "$home_dir/dst-dedicated-server" ]; then
        echo "检测到饥荒服务器目录: $home_dir/dst-dedicated-server"
        return 0
    else
        return 1
    fi
}

# 检查FRP客户端是否已安装
check_frp_client_exist() {
    # 判断是否为root用户
    current_user=$(whoami)
    if [ "$current_user" = "root" ]; then
        frp_dir="/usr/local/frp"  
    else
        frp_dir="/home/$current_user/frp"  
    fi
    
    if [ -f "$frp_dir/frpc.toml" ]; then
        echo "检测到FRP客户端文件"
        return 0
    else
        return 1
    fi
}

# 安装SteamCMD和饥荒服务器
install_steamcmd_and_dst() {
    echo "====== 安装SteamCMD和饥荒服务器 ======"
    
    # 创建steamcmd目录并进入
    echo "创建steamcmd目录: $steamcmd_dir"
    mkdir -p "$steamcmd_dir" || {
        red_echo "无法创建steamcmd目录: $steamcmd_dir"
        return 1
    }
    cd "$steamcmd_dir" || {
        red_echo "无法进入steamcmd目录: $steamcmd_dir"
        return 1
    }
    
    # 下载并安装SteamCMD - 使用多源下载机制（保留官方源和作者源，补充国内源）
    echo "下载SteamCMD (使用多源加速)..."
    steamcmd_downloaded=0
    steamcmd_file="steamcmd_linux.tar.gz"
    
    # 先删除可能存在的不完整文件
    rm -f "$steamcmd_file"
    rm -rf linux32 linux64  # 清除可能残留的旧文件
    
    # 作者提供的2025可用镜像源（优先尝试）
    author_url="http://47.108.31.40:5244/d/myfiles/steamcmd_linux.tar.gz?sign=o003faMBqzluNbu9T506t-Y2f2Yf49XMcw5y_iyF8Rc=:0"
    # 原有国内源和官方源
    aliyun_url="https://mirrors.aliyun.com/steamcmd/linux/$steamcmd_file"
    tencent_url="https://mirrors.cloud.tencent.com/steamcmd/linux/$steamcmd_file"
    official_url="https://steamcdn-a.akamaihd.net/client/installer/$steamcmd_file"
    
    # 尝试作者源
    if wget "$author_url" --progress=bar:force -O "$steamcmd_file"; then
        steamcmd_downloaded=1
    else
        # 尝试阿里云源
        echo "作者源下载失败，尝试阿里云源..."
        if wget "$aliyun_url" --progress=bar:force; then
            steamcmd_downloaded=1
        else
            # 尝试腾讯云源
            echo "阿里云源下载失败，尝试腾讯云源..."
            if wget "$tencent_url" --progress=bar:force; then
                steamcmd_downloaded=1
            else
                # 尝试官方源
                echo "腾讯云源下载失败，尝试官方源..."
                if wget "$official_url" --progress=bar:force; then
                    steamcmd_downloaded=1
                fi
            fi
        fi
    fi
    
    # 检查下载是否成功
    if [ $steamcmd_downloaded -eq 0 ]; then
        red_echo "所有源均下载失败，请检查网络连接或手动下载SteamCMD并放置到 $steamcmd_dir"
        return 1
    fi
    
    # 验证文件完整性
    echo "验证SteamCMD安装包完整性..."
    if ! tar -tzf "$steamcmd_file" >/dev/null 2>&1; then
        red_echo "SteamCMD安装包损坏！"
        rm -f "$steamcmd_file"
        return 1
    fi
    
    # 解压文件
    echo "解压SteamCMD安装包..."
    if ! tar -xvzf "$steamcmd_file"; then
        red_echo "解压SteamCMD失败！可能是安装包损坏"
        rm -f "$steamcmd_file"
        return 1
    fi
    
    # 关键检测：检查steamcmd.sh和32位执行文件是否存在
    if [ ! -f "$steamcmd_dir/steamcmd.sh" ]; then
        red_echo "SteamCMD安装失败：未找到steamcmd.sh文件"
        rm -f "$steamcmd_file"
        return 1
    fi
    
    if [ ! -f "$steamcmd_dir/linux32/steamcmd" ]; then
        red_echo "SteamCMD安装失败：未找到linux32/steamcmd执行文件"
        
        # 尝试修复：安装32位库并重新解压
        echo "尝试安装必要的32位运行库..."
        sudo apt-get install -y lib32gcc-s1 lib32stdc++6
        
        echo "尝试重新解压安装包..."
        rm -rf linux32 linux64
        if ! tar -xvzf "$steamcmd_file"; then
            red_echo "重新解压也失败，请手动安装SteamCMD"
            rm -f "$steamcmd_file"
            return 1
        fi
        
        # 再次检查
        if [ ! -f "$steamcmd_dir/linux32/steamcmd" ]; then
            red_echo "仍然无法找到必要文件，请手动安装SteamCMD"
            rm -f "$steamcmd_file"
            return 1
        fi
    fi
    
    # 确保执行权限
    chmod +x "$steamcmd_dir/steamcmd.sh"
    chmod +x "$steamcmd_dir/linux32/steamcmd"
    
    # 安装饥荒联机版
    echo "安装饥荒联机版服务器..."
    if ! ./steamcmd.sh +login anonymous +force_install_dir ~/dst-dedicated-server +app_update 343050 validate +quit; then
        red_echo "饥荒服务器安装失败！"
        return 1
    fi
    
    # 复制必要的库文件
    echo "复制必要的库文件..."
    if [ ! -f "$steamcmd_dir/linux32/libstdc++.so.6" ]; then
        red_echo "警告：未找到必要的库文件 $steamcmd_dir/linux32/libstdc++.so.6"
    else
        cp "$steamcmd_dir/linux32/libstdc++.so.6" ~/dst-dedicated-server/bin/lib32/ || {
            red_echo "库文件复制失败！"
            return 1
        }
    fi
    
    # 创建服务器配置文件目录
    echo "创建服务器配置文件目录..."
    mkdir -p ~/.klei/DoNotStarveTogether/MyDediServer || {
        red_echo "无法创建服务器配置目录！"
        return 1
    }
    
    green_echo "SteamCMD和饥荒服务器安装完成！"
    return 0
}

# 修改面板配置文件
modify_dst_config() {
    echo "正在修改面板配置文件..."
    local config_file="$dest_dir/dst_config"
    
    if [ ! -f "$config_file" ]; then
        echo "警告：未找到配置文件 $config_file"
        return 1
    fi
    
    # 备份原配置文件
    cp "$config_file" "${config_file}.bak"
    
    # 替换路径为实际路径
    sed -i "s|steamcmd=/root/steamcmd|steamcmd=$steamcmd_dir|g" "$config_file"
    sed -i "s|force_install_dir=/root/dst-dedicated-server|force_install_dir=$home_dir/dst-dedicated-server|g" "$config_file"
    sed -i "s|donot_starve_server_directory=|donot_starve_server_directory=$home_dir/dst-dedicated-server|g" "$config_file"
    sed -i "s|persistent_storage_root=|persistent_storage_root=$home_dir/.klei/DoNotStarveTogether|g" "$config_file"
    sed -i "s|backup=/root/.klei/DoNotStarveTogether|backup=$home_dir/.klei/DoNotStarveTogether|g" "$config_file"
    sed -i "s|mod_download_path=/root/.klei/DoNotStarveTogether|mod_download_path=$home_dir/.klei/DoNotStarveTogether|g" "$config_file"
    
    echo "面板配置文件修改完成！"
}

# 解压文件函数（添加错误处理和重试机制）
extract_file() {
    local file_path="$1"
    local dest_dir="$2"
    local max_attempts=3
    local attempt=1
    
    while [ $attempt -le $max_attempts ]; do
        echo "解压尝试 $attempt/$max_attempts: $file_path"
        
        # 解压文件，忽略Mac扩展属性以避免警告
        if tar -xzvf "$file_path" -C "$dest_dir" --exclude="._*" --exclude=".DS_Store"; then
            echo "解压成功"
            return 0
        else
            echo "解压失败，尝试重新解压..."
            attempt=$((attempt + 1))
            sleep 2
        fi
    done
    
    red_echo "超过最大尝试次数 ($max_attempts)，解压失败"
    return 1
}

# MOD下载修复功能
fix_mod_download() {
    echo "====== MOD下载修复功能 ======"
    
    # 询问用户是否要锁死文件
    echo "请选择操作模式："
    echo "1) 普通修复（只复制文件，不锁死权限）"
    echo "2) 安全修复（复制文件并锁死为只读权限）"
    read -p "请输入选项 (1-2，默认1): " lock_choice
    lock_choice=${lock_choice:-1}
    
    case $lock_choice in
        1)
            lock_files=false
            echo "选择普通修复模式"
            ;;
        2)
            lock_files=true
            echo "选择安全修复模式（文件将被设置为只读）"
            ;;
        *)
            red_echo "无效选择，使用默认模式：普通修复"
            lock_files=false
            ;;
    esac
    
    echo "请选择要修复的服务器版本："
    PS3="请输入数字选择："
    select version in "正式服" "测试服" "取消"; do
        case $REPLY in
            1)
                echo "修复正式服..."
                server_dir="$home_dir/dst-dedicated-server"
                break
                ;;
            2)
                echo "修复测试服..."
                server_dir="$home_dir/dst-dedicated-server-beta"
                break
                ;;
            3)
                echo "操作已取消。"
                return 0
                ;;
            *)
                echo "无效选择！"
                ;;
        esac
    done

    # 检查服务器目录是否存在
    if [ ! -d "$server_dir" ]; then
        echo "错误：未找到服务器目录 $server_dir"
        echo "请先安装相应的服务器版本。"
        return 1
    fi

    # 定义源文件路径和目标路径
    source_32="$steamcmd_dir/linux32/steamclient.so"
    destination_32="$server_dir/bin/lib32/steamclient.so"
    backup_dir_32="$server_dir/bin/lib32/backup"

    source_64="$steamcmd_dir/linux64/steamclient.so"
    destination_64_1="$server_dir/linux64/steamclient.so"
    destination_64_2="$server_dir/bin64/lib64/steamclient.so"
    backup_dir_64_1="$server_dir/linux64/backup"
    backup_dir_64_2="$server_dir/bin64/lib64/backup"

    # 创建备份目录（如果不存在）
    mkdir -p "$backup_dir_32" "$backup_dir_64_1" "$backup_dir_64_2"

    # 备份并复制函数 - 根据用户选择决定是否锁死文件
    backup_and_copy() {
        local source=$1
        local destination=$2
        local backup_dir=$3
        local backup_file="$backup_dir/steamclient.so_$(date +"%Y%m%d_%H%M%S")"

        # 检查源文件是否存在
        if [ ! -f "$source" ]; then
            echo "错误：源文件不存在 $source"
            return 1
        fi

        # 检查目标文件是否存在，如果存在则备份
        if [ -f "$destination" ]; then
            # 备份原文件
            cp "$destination" "$backup_file"
            if [ $? -eq 0 ]; then
                echo "备份成功: $backup_file"
            else
                echo "备份失败！"
                return 1
            fi
        fi

        # 复制新文件
        cp "$source" "$destination"
        if [ $? -eq 0 ]; then
            echo "复制成功: $destination"
            
            # 根据用户选择设置文件权限
            if [ "$lock_files" = true ]; then
                # 安全模式：设置文件为只读（锁死）
                chmod 444 "$destination"
                if [ $? -eq 0 ]; then
                    echo "已设置文件为只读权限: $destination"
                else
                    echo "警告：设置只读权限失败"
                fi
            else
                # 普通模式：保持正常权限（644）
                echo "文件保持正常权限"
            fi
        else
            echo "复制失败！"
            return 1
        fi
    }

    # 执行32位文件的备份和复制
    echo "修复32位文件..."
    if [ -f "$source_32" ]; then
        backup_and_copy "$source_32" "$destination_32" "$backup_dir_32"
    else
        echo "警告：未找到32位源文件 $source_32"
    fi

    # 执行64位文件的备份和复制（第一个目标）
    echo "修复64位文件（第一个目标）..."
    if [ -f "$source_64" ] && [ -d "$(dirname "$destination_64_1")" ]; then
        backup_and_copy "$source_64" "$destination_64_1" "$backup_dir_64_1"
    else
        echo "警告：未找到64位源文件或目标目录不存在"
    fi

    # 执行64位文件的备份和复制（第二个目标）
    echo "修复64位文件（第二个目标）..."
    if [ -f "$source_64" ] && [ -d "$(dirname "$destination_64_2")" ]; then
        backup_and_copy "$source_64" "$destination_64_2" "$backup_dir_64_2"
    else
        echo "警告：未找到64位源文件或目标目录不存在"
    fi

    # 显示最终结果
    echo ""
    echo "MOD下载修复完成！"
    if [ "$lock_files" = true ]; then
        yellow_echo "安全模式：文件已被设置为只读权限（444）"
        yellow_echo "如需修改这些文件，需要先使用 chmod 644 命令取消只读权限"
    else
        green_echo "普通模式：文件保持正常权限（644）"
    fi
    echo "所有原始文件已备份到相应的 backup 目录中"
}

# 重装与重置功能模块
reinstall_menu() {
    green_echo "====== 重装与重置功能 ======"
    echo "请选择需要执行的操作："
    echo "1) 重装 steamcmd"
    echo "2) 面板程序重装"
    echo "3) 正式服服务器重置"
    echo "4) 测试服服务器重置"
    echo "5) 全部重装（包含steamcmd、面板程序、正式服）"  # 修改描述
    echo "0) 返回上级菜单"
    
    read -p "请输入选项 (0-5): " choice
    case $choice in
        1)
            reinstall_steamcmd
            ;;
        2)
            reinstall_panel
            ;;
        3)
            reset_official_server
            ;;
        4)
            reset_test_server
            ;;
        5)
            # 修改确认提示信息，明确不包含测试服
            if ask_yes_no "确定要执行全部重装操作吗？这将删除现有配置并重新安装steamcmd、面板程序和正式服服务器" "N"; then
                reinstall_steamcmd
                reinstall_panel
                reset_official_server  # 保留正式服相关操作
                # 移除测试服重置操作 reset_test_server
                green_echo "全部重装操作已完成（不包含测试服）"  # 更新完成提示
            else
                yellow_echo "已取消全部重装操作"
            fi
            ;;
        0)
            echo "返回上级菜单"
            return 0
            ;;
        *)
            red_echo "无效选项，请重新输入"
            reinstall_menu
            ;;
    esac
}

# 重装 steamcmd
reinstall_steamcmd() {
    green_echo "====== 重装 steamcmd ======"
    
    if [ -d "$steamcmd_dir" ]; then
        yellow_echo "检测到已安装 steamcmd，正在卸载..."
        if sudo rm -rf "$steamcmd_dir"; then
            green_echo "旧版 steamcmd 已删除"
        else
            red_echo "删除旧版 steamcmd 失败，请检查权限"
            return 1
        fi
    fi
    
    yellow_echo "开始安装 steamcmd..."
    mkdir -p "$steamcmd_dir"
    cd "$steamcmd_dir" || { red_echo "无法进入 steamcmd 目录"; return 1; }
    
    # 下载并安装 steamcmd
    if ! wget https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz -O steamcmd_linux.tar.gz; then
        red_echo "下载 steamcmd 失败"
        return 1
    fi
    
    tar -zxf steamcmd_linux.tar.gz
    rm -f steamcmd_linux.tar.gz
    
    # 验证安装
    if [ -f "$steamcmd_dir/steamcmd.sh" ]; then
        green_echo "steamcmd 重装完成"
    else
        red_echo "steamcmd 重装失败"
        return 1
    fi
}

# 面板程序重装
reinstall_panel() {
    green_echo "====== 面板程序重装 ======"
    
    if [ ! -d "$dest_dir" ]; then
        yellow_echo "未检测到已安装的面板，将执行全新安装"
    else
        # 备份配置文件
        yellow_echo "正在备份配置文件..."
        config_backup="$home_dir/dst_config_backup_$(date +%Y%m%d%H%M%S)"
        mkdir -p "$config_backup"
        
        if [ -f "$dest_dir/config.yml" ]; then
            cp "$dest_dir/config.yml" "$config_backup/" && green_echo "已备份 config.yml"
        fi
        
        if [ -d "$dest_dir/data" ]; then
            cp -r "$dest_dir/data" "$config_backup/" && green_echo "已备份数据目录"
        fi
        
        # 删除旧面板文件
        yellow_echo "正在删除旧版面板..."
        if ! rm -rf "$dest_dir"/*; then
            red_echo "删除旧版面板失败，请检查权限"
            return 1
        fi
    fi
    
    # 重新安装面板（这里假设面板安装命令，实际应根据原脚本逻辑调整）
    yellow_echo "开始重新安装面板..."
    mkdir -p "$dest_dir"
    cd "$dest_dir" || { red_echo "无法进入目标目录"; return 1; }
    
    # 此处应添加实际的面板安装命令
    # 示例：wget <面板下载地址> -O dst-admin && chmod +x dst-admin
    
    # 恢复配置文件
    if [ -d "$config_backup" ]; then
        yellow_echo "正在恢复配置文件..."
        [ -f "$config_backup/config.yml" ] && cp "$config_backup/config.yml" "$dest_dir/"
        [ -d "$config_backup/data" ] && cp -r "$config_backup/data" "$dest_dir/"
    fi
    
    green_echo "面板程序重装完成"
}

# 正式服服务器重置
reset_official_server() {
    green_echo "====== 正式服服务器重置 ======"
    local server_dir="$home_dir/.klei/DoNotStarveTogether/MyDediServer"
    
    if [ ! -d "$server_dir" ]; then
        yellow_echo "未检测到正式服服务器，将执行全新安装"
    else
        if ask_yes_no "确定要重置正式服服务器吗？这将删除现有服务器文件但保留存档" "N"; then
            # 备份存档
            local save_backup="$home_dir/dst_save_backup_$(date +%Y%m%d%H%M%S)"
            mkdir -p "$save_backup"
            
            if [ -d "$server_dir/Cluster_1" ]; then
                cp -r "$server_dir/Cluster_1" "$save_backup/" && green_echo "已备份正式服存档"
            fi
            
            # 删除服务器文件
            rm -rf "$server_dir"/*
        else
            yellow_echo "已取消正式服重置"
            return 0
        fi
    fi
    
    # 重新安装正式服（这里假设安装命令，实际应根据原脚本逻辑调整）
    yellow_echo "开始重新安装正式服服务器..."
    mkdir -p "$server_dir"
    
    # 此处应添加实际的服务器安装命令
    # 示例：$steamcmd_dir/steamcmd.sh +login anonymous +app_update 343050 validate +quit
    
    # 恢复存档
    if [ -d "$save_backup/Cluster_1" ]; then
        yellow_echo "正在恢复正式服存档..."
        cp -r "$save_backup/Cluster_1" "$server_dir/"
    fi
    
    green_echo "正式服服务器重置完成"
}

# 测试服服务器重置
reset_test_server() {
    green_echo "====== 测试服服务器重置 ======"
    local test_server_dir="$home_dir/.klei/DoNotStarveTogether/MyTestServer"
    
    if [ ! -d "$test_server_dir" ]; then
        yellow_echo "未检测到测试服服务器，将执行全新安装"
    else
        if ask_yes_no "确定要重置测试服服务器吗？这将删除现有服务器文件但保留存档" "N"; then
            # 备份存档
            local test_save_backup="$home_dir/dst_test_save_backup_$(date +%Y%m%d%H%M%S)"
            mkdir -p "$test_save_backup"
            
            if [ -d "$test_server_dir/Cluster_1" ]; then
                cp -r "$test_server_dir/Cluster_1" "$test_save_backup/" && green_echo "已备份测试服存档"
            fi
            
            # 删除服务器文件
            rm -rf "$test_server_dir"/*
        else
            yellow_echo "已取消测试服重置"
            return 0
        fi
    fi
    
    # 重新安装测试服（这里假设安装命令，实际应根据原脚本逻辑调整）
    yellow_echo "开始重新安装测试服服务器..."
    mkdir -p "$test_server_dir"
    
    # 此处应添加实际的测试服安装命令
    # 示例：$steamcmd_dir/steamcmd.sh +login anonymous +app_update 343050 -beta preview validate +quit
    
    # 恢复存档
    if [ -d "$test_save_backup/Cluster_1" ]; then
        yellow_echo "正在恢复测试服存档..."
        cp -r "$test_save_backup/Cluster_1" "$test_server_dir/"
    fi
    
    green_echo "测试服服务器重置完成"
}

# LuaJIT版本检测函数
check_luajit_version() {
    local luajit_dir="$home_dir/luajit"
    local version_file="$luajit_dir/version.txt"
    
    if [ -f "$version_file" ]; then
        local installed_version=$(cat "$version_file" 2>/dev/null)
        echo "$installed_version"
        return 0
    elif [ -d "$luajit_dir" ]; then
        # 检测目录存在但没有版本文件，默认为1.0
        echo "1.0"
        return 0
    else
        echo ""
        return 1
    fi
}

# LuaJIT管理主函数
manage_luajit() {
    echo "====== LuaJIT 性能优化模块管理 ======"
    red_echo "【重要提醒】小白不懂不要装LuaJIT！"
    yellow_echo "LuaJIT是第三方性能优化模块，安装不当可能导致服务器无法启动！"
    yellow_echo "建议在安装前备份服务器存档和配置！"
    echo ""
    
    # 检测当前安装的版本
    local current_version=$(check_luajit_version)
    
    if [ -n "$current_version" ]; then
        green_echo "检测到已安装 LuaJIT $current_version"
        echo ""
    fi

    while true; do
        echo "请选择操作："
        if [ -n "$current_version" ]; then
            echo "1) 卸载当前 LuaJIT $current_version"
            echo "2) 切换到 LuaJIT 1.0"
            echo "3) 切换到 LuaJIT 2.0"
        else
            echo "1) 安装 LuaJIT 1.0"
            echo "2) 安装 LuaJIT 2.0"
        fi
        echo "0) 返回主菜单"
        read -p "请输入选项: " choice

        case $choice in
            1)
                if [ -n "$current_version" ]; then
                    # 卸载当前版本
                    echo "正在卸载 LuaJIT $current_version..."
                    if [ "$current_version" = "1.0" ]; then
                        uninstall_luajit1
                    else
                        uninstall_luajit2
                    fi
                    current_version=""
                else
                    # 安装 LuaJIT 1.0
                    install_luajit1_prompt
                    if [ $? -eq 0 ]; then
                        current_version="1.0"
                    fi
                fi
                ;;
            2)
                if [ -n "$current_version" ]; then
                    # 切换到 LuaJIT 1.0
                    if [ "$current_version" = "1.0" ]; then
                        yellow_echo "当前已经是 LuaJIT 1.0，无需切换"
                    else
                        echo "需要先卸载 LuaJIT 2.0 才能安装 LuaJIT 1.0"
                        if ask_yes_no "确定要卸载 LuaJIT 2.0 并安装 LuaJIT 1.0 吗？" "N"; then
                            uninstall_luajit2
                            install_luajit1_prompt
                            if [ $? -eq 0 ]; then
                                current_version="1.0"
                            fi
                        fi
                    fi
                else
                    # 安装 LuaJIT 2.0
                    install_luajit2_prompt
                    if [ $? -eq 0 ]; then
                        current_version="2.0"
                    fi
                fi
                ;;
            3)
                if [ -n "$current_version" ]; then
                    # 切换到 LuaJIT 2.0
                    if [ "$current_version" = "2.0" ]; then
                        yellow_echo "当前已经是 LuaJIT 2.0，无需切换"
                    else
                        echo "需要先卸载 LuaJIT 1.0 才能安装 LuaJIT 2.0"
                        if ask_yes_no "确定要卸载 LuaJIT 1.0 并安装 LuaJIT 2.0 吗？" "N"; then
                            uninstall_luajit1
                            install_luajit2_prompt
                            if [ $? -eq 0 ]; then
                                current_version="2.0"
                            fi
                        fi
                    fi
                else
                    yellow_echo "无效选项"
                fi
                ;;
            0)
                return 0
                ;;
            *)
                red_echo "无效的选项，请重新输入！"
                ;;
        esac
        
        echo ""
        read -p "按回车键继续..."
        echo ""
    done
}

# --- LuaJIT 1.0 安装核心逻辑 ---
_install_luajit1_core() {
    green_echo "正在准备安装 luajit 1.0..."
    
    # 使用当前用户目录
    luajit_dir="$home_dir/luajit"
    green_echo "创建 $luajit_dir 目录并进入..."
    mkdir -p "$luajit_dir" && cd "$luajit_dir"

    green_echo "正在下载 luajit 1.0 安装包..."
    if ! wget "http://47.108.31.40:5244/d/myfiles/linux_x86_64.tar.gz?sign=PF9muRAfHbQsCvKjGe3QOCM7cTl1diflymJZnHWEepE=:0" -O linux_x86_64.tar.gz; then
        red_echo "下载失败！请检查网络连接。"
        return 1
    fi

    green_echo "正在解压安装包..."
    if ! tar -zxvf linux_x86_64.tar.gz; then
        red_echo "解压失败！文件可能已损坏。"
        return 1
    fi

    green_echo "正在执行 luajit 1.0 安装..."
    
    # 检查setup.sh是否存在
    if [ ! -f "./setup.sh" ]; then
        red_echo "错误：未找到 setup.sh 安装脚本"
        return 1
    fi
    
    # 使用正确的饥荒服务器路径
    dst_server_dir="$home_dir/dst-dedicated-server"
    if [ ! -d "$dst_server_dir" ]; then
        red_echo "错误：未找到饥荒服务器目录 $dst_server_dir"
        red_echo "请先安装饥荒服务器！"
        return 1
    fi
    
    # 执行安装
    if sh ./setup.sh "$dst_server_dir" install; then
        green_echo "luajit 1.0 安装完成。请到面板切换luajit启动游戏 注意先备份存档"
        green_echo "安装目录: $luajit_dir"
        green_echo "目标服务器: $dst_server_dir"
        
        # 写入版本号文件
        echo "1.0" > "$luajit_dir/version.txt"
    else
        red_echo "luajit 1.0 安装失败！"
        return 1
    fi
}

# --- LuaJIT 1.0 安装引导函数  ---
install_luajit1_prompt() {
    # 检查是否已安装饥荒服务器
    if [ ! -d "$home_dir/dst-dedicated-server" ]; then
        red_echo "错误：未找到饥荒服务器目录！"
        red_echo "请先安装饥荒服务器再安装LuaJIT 1.0。"
        return 1
    fi

    version_id=""
    if [ -f /etc/os-release ]; then
        . /etc/os-release
    else
        red_echo "警告: 无法检测到系统版本，将跳过 luajit 1.0 兼容性检查。"
    fi

    # 情况一：检测到不兼容版本
    if [[ "$version_id" == "18.04" || "$version_id" == "20.04" ]]; then
        red_echo "----------------------------------------------------------------"
        red_echo "【警告】检测到当前系统为 Ubuntu ${version_id}。"
        red_echo "根据测试，luajit 1.0 在此版本上可能不会生效。"
        red_echo "强烈建议您将系统升级至 Ubuntu 22.04 或更高版本！"
        red_echo "----------------------------------------------------------------"
        if ask_yes_no "尽管存在兼容性风险，你依然要强制安装 luajit 1.0 吗？" "N"; then
            _install_luajit1_core
        else
            green_echo "已根据建议取消安装 luajit 1.0。"
        fi
    # 情况二：兼容版本或未知版本
    else
        yellow_echo "------------------------- LuaJIT 1.0 性能说明 -------------------------"
        yellow_echo "原版饥荒服务器支持32位和64位启动方式,LuaJIT是民间大神做的扩展。"
        yellow_echo " - 32位: 优点是占用内存较少。"
        yellow_echo " - 64位: 占用内存稍多，但运行更流畅，能容纳更多动态生物（约10%）。"
        yellow_echo " - LuaJIT 1.0: 内存占用与64位相当，但在处理大量静态物品（如武器、护甲）时，"
        yellow_echo "           相比64位模式可节省约 5%-10% 的CPU占用。对动态生物（玩家、怪物）的提升不明显。"
        yellow_echo "--------------------------------------------------------------------"
        green_echo "当前系统版本经过测试，理论上兼容 luajit 1.0。"
        yellow_echo "但请注意：这不保证在所有环境下都能 100% 成功生效或带来预期提升。"

        if ask_yes_no "了解以上信息后，你确定要安装 luajit 1.0 吗？" "Y"; then
            _install_luajit1_core
        else
            green_echo "已取消安装 luajit 1.0。"
        fi
    fi
}

# --- LuaJIT 2.0 安装核心逻辑 ---
_install_luajit2_core() {
    green_echo "正在准备安装 luajit 2.0..."
    
    # 配置变量
    MOD_DOWNLOAD_URL="http://47.108.31.40:5244/d/myfiles/linux_Mod.zip?sign=tbCj2HISBP9KtJP1cRqbFy8ZTbY6vHVxnP3capOgeaM=:0"
    ZIP_FILE="linux_MOD.zip"
    DST_SERVER_ROOT="$home_dir/dst-dedicated-server"
    MOD_INSTALL_NAME="luajit_mod"
    EXTRACTED_FOLDER_NAME="Mod"

    # 确保在脚本开始时位于用户目录
    cd "$home_dir" || {
        red_echo "无法切换到用户目录 $home_dir，请检查权限。"
        return 1
    }

    # 检查并安装依赖工具
    green_echo "正在检查依赖工具..."
    PACKAGES_TO_INSTALL=""
    if ! command -v wget &> /dev/null; then
        PACKAGES_TO_INSTALL+="wget "
    fi
    if ! command -v unzip &> /dev/null; then
        PACKAGES_TO_INSTALL+="unzip "
    fi

    if [ -n "$PACKAGES_TO_INSTALL" ]; then
        green_echo "检测到未安装的工具: $PACKAGES_TO_INSTALL"
        green_echo "正在尝试自动安装 (需要sudo权限)..."
        # 探测包管理器
        if command -v apt-get &> /dev/null; then
            sudo apt-get update && sudo apt-get install -y $PACKAGES_TO_INSTALL
        elif command -v yum &> /dev/null; then
            sudo yum install -y $PACKAGES_TO_INSTALL
        elif command -v dnf &> /dev/null; then
            sudo dnf install -y $PACKAGES_TO_INSTALL
        else
            red_echo "无法确定包管理器，请手动安装: $PACKAGES_TO_INSTALL"
            return 1
        fi

        if [ $? -ne 0 ]; then
            red_echo "依赖工具安装失败，请手动安装后再运行脚本。"
            return 1
        else
            green_echo "依赖工具安装成功。"
        fi
    else
        green_echo "依赖工具已全部安装。"
    fi

    # 下载插件
    green_echo "正在下载插件压缩包..."
    [ -f "$ZIP_FILE" ] && rm -f "$ZIP_FILE"
    if wget -O "$ZIP_FILE" "$MOD_DOWNLOAD_URL"; then
        green_echo "插件下载成功。"
    else
        red_echo "插件下载失败，请检查网络或URL是否有效。"
        return 1
    fi

    # 解压插件
    green_echo "正在解压插件..."
    [ -d "$EXTRACTED_FOLDER_NAME" ] && rm -rf "$EXTRACTED_FOLDER_NAME"
    if unzip -o "$ZIP_FILE"; then
        green_echo "插件解压成功。"
    else
        red_echo "插件解压失败。"
        return 1
    fi

    # 安装MOD本体
    green_echo "开始安装MOD本体..."
    MODS_TARGET_DIR="$DST_SERVER_ROOT/mods/$MOD_INSTALL_NAME"
    mkdir -p "$MODS_TARGET_DIR" || {
        red_echo "创建MOD目录 $MODS_TARGET_DIR 失败。"
        return 1
    }
    cp -r ${EXTRACTED_FOLDER_NAME}/* "$MODS_TARGET_DIR/" || {
        red_echo "复制MOD文件失败。"
        return 1
    }
    green_echo "MOD本体已成功安装到 $MODS_TARGET_DIR"

    # 复制bin64文件
    green_echo "开始处理bin64目录文件..."
    BIN64_TARGET_DIR="$DST_SERVER_ROOT/bin64"
    BIN64_SOURCE_DIR="${EXTRACTED_FOLDER_NAME}/bin64/linux"

    if [ ! -d "$BIN64_SOURCE_DIR" ]; then
        red_echo "解压文件中未找到源目录: $home_dir/$BIN64_SOURCE_DIR"
        return 1
    fi
    if [ ! -d "$BIN64_TARGET_DIR" ]; then
        red_echo "目标服务器目录不存在: $BIN64_TARGET_DIR"
        return 1
    fi

    green_echo "正在从 $BIN64_SOURCE_DIR 复制文件到 $BIN64_TARGET_DIR"
    # 使用-T选项可以防止cp把源目录本身也复制过去
    cp -r "$home_dir/${BIN64_SOURCE_DIR}/." "$BIN64_TARGET_DIR/" || {
        red_echo "复制bin64文件失败。"
        return 1
    }

    # 创建新的启动脚本 (服务器专用逻辑)
    green_echo "正在为服务器创建新的启动脚本..."
    cd "$BIN64_TARGET_DIR" || {
        red_echo "无法进入目录 $BIN64_TARGET_DIR"
        return 1
    }

    ORIGINAL_EXEC="dontstarve_dedicated_server_nullrenderer_x64"
    WRAPPER_EXEC="dontstarve_dedicated_server_nullrenderer_x64_luajit"

    # 检查原始服务器文件是否存在，这是一个关键的健全性检查
    if [ ! -f "$ORIGINAL_EXEC" ]; then
        red_echo "错误：原始服务器执行文件 '$ORIGINAL_EXEC' 不存在于 $BIN64_TARGET_DIR。请确认服务器已正确安装。"
        return 1
    fi

    green_echo "正在创建新的luajit启动脚本: $WRAPPER_EXEC"
    cat > "$WRAPPER_EXEC" << 'EOF'
#!/bin/bash
export LD_LIBRARY_PATH=./lib64
export LD_PRELOAD=./lib64/libInjector.so
./dontstarve_dedicated_server_nullrenderer_x64 "$@"
EOF
    green_echo "luajit脚本创建成功。"

    # 赋予执行权限
    green_echo "正在为包装器脚本赋予执行权限..."
    chmod +x "$WRAPPER_EXEC" || {
        red_echo "设置执行权限失败。"
        return 1
    }

    # 清理工作
    green_echo "清理下载的临时文件..."
    cd "$home_dir"
    rm -f "$ZIP_FILE"
    rm -rf "$EXTRACTED_FOLDER_NAME"
    green_echo "清理完成。"

    # 写入版本号文件
    luajit_dir="$home_dir/luajit"
    mkdir -p "$luajit_dir"
    echo "2.0" > "$luajit_dir/version.txt"

    green_echo "LuaJIT 2.0 所有步骤已成功完成！"
    yellow_echo "重要提示：LuaJIT 2.0 需要写入mods，可能会有mod不兼容问题，小白请谨慎使用！"
    green_echo "请到面板切换luajit启动游戏，注意先备份存档！"
}

# --- LuaJIT 2.0 安装引导函数 ---
install_luajit2_prompt() {
    # 检查是否已安装饥荒服务器
    if [ ! -d "$home_dir/dst-dedicated-server" ]; then
        red_echo "错误：未找到饥荒服务器目录！"
        red_echo "请先安装饥荒服务器再安装LuaJIT 2.0。"
        return 1
    fi

    yellow_echo "======================== LuaJIT 2.0 安装警告 ========================"
    red_echo "【重要提醒】LuaJIT 2.0 需要写入mods目录，可能会有mod不兼容问题！"
    yellow_echo "- LuaJIT 2.0 使用不同的技术实现，相比1.0版本有更好的性能"
    yellow_echo "- 但是可能会与某些MOD产生冲突，导致服务器无法启动"
    yellow_echo "- 建议在安装前备份当前服务器和存档"
    yellow_echo "- 两个LuaJIT版本不能共存，切换需要先卸载再安装"
    yellow_echo "===================================================================="
    
    if ! ask_yes_no "了解以上风险后，你确定要安装 LuaJIT 2.0 吗？" "N"; then
        green_echo "已取消安装 LuaJIT 2.0。"
        return 0
    fi

    _install_luajit2_core
}

# --- 卸载 LuaJIT 1.0 ---
uninstall_luajit1() {
    echo "====== 卸载 LuaJIT 1.0 ======"
    
    # 检查是否已安装饥荒服务器
    if [ ! -d "$home_dir/dst-dedicated-server" ]; then
        red_echo "错误：未找到饥荒服务器目录！"
        return 1
    fi

    yellow_echo "警告：此操作将删除饥荒服务器并重新安装，但会保留存档和MOD配置。"
    if ! ask_yes_no "确定要卸载 LuaJIT 1.0 并重新安装饥荒服务器吗？" "N"; then
        echo "已取消卸载操作。"
        return 0
    fi

    # 备份重要目录
    backup_dir="$home_dir/dst-backup-$(date +%Y%m%d%H%M%S)"
    echo "创建备份目录: $backup_dir"
    mkdir -p "$backup_dir"
    
    # 备份存档和MOD配置
    if [ -d "$home_dir/.klei" ]; then
        echo "备份存档目录..."
        cp -r "$home_dir/.klei" "$backup_dir/" || echo "警告：存档备份失败"
    fi
    
    if [ -d "$home_dir/Steam" ]; then
        echo "备份Steam配置..."
        cp -r "$home_dir/Steam" "$backup_dir/" || echo "警告：Steam配置备份失败"
    fi

    # 删除饥荒服务器目录
    echo "删除饥荒服务器目录..."
    rm -rf "$home_dir/dst-dedicated-server"
    
    # 删除LuaJIT 1.0目录
    if [ -d "$home_dir/luajit" ]; then
        echo "删除LuaJIT 1.0目录..."
        rm -rf "$home_dir/luajit"
    fi

    # 重新安装饥荒服务器
    echo "重新安装饥荒服务器..."
    install_steamcmd_and_dst

    # 恢复备份
    if [ -d "$backup_dir/.klei" ]; then
        echo "恢复存档目录..."
        cp -r "$backup_dir/.klei" "$home_dir/" || echo "警告：存档恢复失败"
    fi
    
    green_echo "LuaJIT 1.0 卸载完成！饥荒服务器已重新安装。"
    echo "备份文件保存在: $backup_dir"
}

# --- 卸载 LuaJIT 2.0 ---
uninstall_luajit2() {
    echo "====== 卸载 LuaJIT 2.0 ======"
    
    # 检查是否已安装饥荒服务器
    if [ ! -d "$home_dir/dst-dedicated-server" ]; then
        red_echo "错误：未找到饥荒服务器目录！"
        return 1
    fi

    yellow_echo "警告：此操作将删除饥荒服务器并重新安装，但会保留存档和MOD配置。"
    if ! ask_yes_no "确定要卸载 LuaJIT 2.0 并重新安装饥荒服务器吗？" "N"; then
        echo "已取消卸载操作。"
        return 0
    fi

    # 备份重要目录
    backup_dir="$home_dir/dst-backup-$(date +%Y%m%d%H%M%S)"
    echo "创建备份目录: $backup_dir"
    mkdir -p "$backup_dir"
    
    # 备份存档和MOD配置
    if [ -d "$home_dir/.klei" ]; then
        echo "备份存档目录..."
        cp -r "$home_dir/.klei" "$backup_dir/" || echo "警告：存档备份失败"
    fi
    
    if [ -d "$home_dir/Steam" ]; then
        echo "备份Steam配置..."
        cp -r "$home_dir/Steam" "$backup_dir/" || echo "警告：Steam配置备份失败"
    fi

    # 删除饥荒服务器目录
    echo "删除饥荒服务器目录..."
    rm -rf "$home_dir/dst-dedicated-server"
    
    # 删除LuaJIT 2.0的MOD文件
    if [ -d "$home_dir/dst-dedicated-server/mods/luajit_mod" ]; then
        echo "删除LuaJIT 2.0 MOD文件..."
        rm -rf "$home_dir/dst-dedicated-server/mods/luajit_mod"
    fi

    # 删除版本文件
    if [ -f "$home_dir/luajit/version.txt" ]; then
        echo "删除版本文件..."
        rm -f "$home_dir/luajit/version.txt"
    fi

    # 重新安装饥荒服务器
    echo "重新安装饥荒服务器..."
    install_steamcmd_and_dst

    # 恢复备份
    if [ -d "$backup_dir/.klei" ]; then
        echo "恢复存档目录..."
        cp -r "$backup_dir/.klei" "$home_dir/" || echo "警告：存档恢复失败"
    fi
    
    green_echo "LuaJIT 2.0 卸载完成！饥荒服务器已重新安装。"
    echo "备份文件保存在: $backup_dir"
}

# --- Teamspeak 3 服务器安装功能 ---
install_teamspeak3_server() {
    echo "====== 安装 Teamspeak 3 语音服务器 ======"
    
    # 配置变量 - 修改为当前用户目录
    TS3_DOWNLOAD_URL="http://47.108.31.40:5244/d/myfiles/teamspeak3-server_linux_amd64-3.13.7.zip?sign=bu-gLAZD-fEywO_acW9s7alPchksCFfi-EX_ANEp6aU=:0"
    TS3_ZIP_FILE="teamspeak3-server_linux_amd64.zip"
    TS3_INSTALL_DIR="$home_dir/teamspeak3"  # 修改为当前用户目录
    TS3_USER="$REAL_user"  # 使用当前用户
    
    yellow_echo "注意：Teamspeak 3 服务器需要以下端口："
    yellow_echo "- 9987 (UDP): 语音数据传输"
    yellow_echo "- 10011 (TCP): 文件传输"
    yellow_echo "- 30033 (TCP): ServerQuery"
    yellow_echo "请确保防火墙已开放这些端口！"
    
    red_echo "【重要提醒】该功能只用于云服务器，本地服务器需要映射！"
    yellow_echo "如果您使用的是本地服务器，需要通过FRP或其他方式映射上述端口到公网。"
    
    if ! ask_yes_no "确定要安装 Teamspeak 3 服务器吗？" "Y"; then
        echo "已取消安装 Teamspeak 3 服务器。"
        return 0
    fi

    # 检查并安装依赖
    green_echo "正在检查依赖工具..."
    if ! command -v wget &> /dev/null; then
        green_echo "安装 wget..."
        sudo apt-get install -y wget
    fi
    if ! command -v unzip &> /dev/null; then
        green_echo "安装 unzip..."
        sudo apt-get install -y unzip
    fi

    # 创建安装目录
    green_echo "创建安装目录..."
    mkdir -p "$TS3_INSTALL_DIR"

    # 下载Teamspeak 3服务器
    green_echo "正在下载 Teamspeak 3 服务器..."
    cd /tmp
    if wget -O "$TS3_ZIP_FILE" "$TS3_DOWNLOAD_URL"; then
        green_echo "下载成功。"
    else
        red_echo "下载失败，请检查网络连接。"
        return 1
    fi

    # 解压文件到临时目录
    green_echo "正在解压文件..."
    local temp_extract_dir=$(mktemp -d)
    if unzip -o "$TS3_ZIP_FILE" -d "$temp_extract_dir"; then
        green_echo "解压成功。"
    else
        red_echo "解压失败。"
        rm -rf "$temp_extract_dir"
        return 1
    fi

    # 查找解压后的所有文件并移动到安装目录
    green_echo "移动文件到安装目录..."
    
    # 查找实际的服务器文件
    local ts3server_path=$(find "$temp_extract_dir" -name "ts3server" -type f | head -1)
    if [ -z "$ts3server_path" ]; then
        red_echo "错误：未找到ts3server文件！"
        echo "解压目录内容："
        find "$temp_extract_dir" -type f -name "*" | head -20
        rm -rf "$temp_extract_dir"
        return 1
    fi
    
    green_echo "找到ts3server文件: $ts3server_path"
    
    # 获取ts3server文件所在的目录
    local ts3_server_dir=$(dirname "$ts3server_path")
    green_echo "Teamspeak服务器目录: $ts3_server_dir"
    
    # 显示服务器目录内容
    echo "服务器目录内容："
    ls -la "$ts3_server_dir"
    
    # 将服务器目录中的所有文件复制到安装目录
    green_echo "复制文件到安装目录..."
    cp -r "$ts3_server_dir"/* "$TS3_INSTALL_DIR/" || {
        red_echo "复制文件失败！"
        rm -rf "$temp_extract_dir"
        return 1
    }
    
    # 清理临时目录
    rm -rf "$temp_extract_dir"
    
    # 检查安装目录内容
    echo "安装目录内容："
    ls -la "$TS3_INSTALL_DIR"

    # 设置权限
    green_echo "设置文件权限..."
    chown -R "$TS3_USER:$TS3_USER" "$TS3_INSTALL_DIR"
    
    # 设置ts3server文件权限
    if [ -f "$TS3_INSTALL_DIR/ts3server" ]; then
        chmod +x "$TS3_INSTALL_DIR/ts3server"
        green_echo "ts3server权限设置成功"
    else
        red_echo "错误：安装目录中未找到ts3server文件！"
        return 1
    fi
    
    # 创建许可接受文件
    green_echo "创建Teamspeak 3许可接受文件..."
    touch "$TS3_INSTALL_DIR/.ts3server_license_accepted"
    chown "$TS3_USER:$TS3_USER" "$TS3_INSTALL_DIR/.ts3server_license_accepted"
    
    # 创建systemd服务文件 - 在安装目录中启动ts3server
    green_echo "创建系统服务..."
    sudo tee /etc/systemd/system/teamspeak3.service > /dev/null <<EOF
[Unit]
Description=TeamSpeak 3 Server
After=network.target

[Service]
Type=simple
User=$TS3_USER
Group=$TS3_USER
WorkingDirectory=$TS3_INSTALL_DIR
ExecStart=$TS3_INSTALL_DIR/ts3server
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

    # 重载systemd并启用服务
    green_echo "配置系统服务..."
    sudo systemctl daemon-reload
    sudo systemctl enable teamspeak3.service

    # 启动服务
    green_echo "启动 Teamspeak 3 服务..."
    if sudo systemctl start teamspeak3.service; then
        green_echo "Teamspeak 3 服务启动成功！"
        
        # 等待服务启动并获取管理员密钥
        green_echo "正在获取管理员密钥..."
        
        # 等待一段时间让服务器生成令牌文件和日志
        sleep 5
        
        # 首先尝试从日志中提取令牌
        green_echo "从系统日志中提取管理员令牌..."
        
        # 使用更精确的方法提取令牌
        ADMIN_TOKEN=$(sudo journalctl -u teamspeak3.service --since "1 minute ago" --no-pager | grep -E "token=[A-Za-z0-9+/]+" | head -1 | sed 's/.*token=//')
        
        if [ -z "$ADMIN_TOKEN" ]; then
            # 如果第一次尝试失败，使用更宽松的匹配
            ADMIN_TOKEN=$(sudo journalctl -u teamspeak3.service --since "1 minute ago" --no-pager | grep -o "token=[^ ]*" | head -1 | cut -d'=' -f2)
        fi
        
        if [ -z "$ADMIN_TOKEN" ]; then
            # 如果还是失败，显示原始日志让用户手动查找
            yellow_echo "自动提取令牌失败，显示相关日志..."
            sudo journalctl -u teamspeak3.service --since "1 minute ago" --no-pager | grep -i -A5 -B5 "token"
            yellow_echo "请从上方日志中手动查找以 'token=' 开头的行，并记录令牌"
            read -p "请输入您找到的令牌: " ADMIN_TOKEN
        fi
        
        if [ -n "$ADMIN_TOKEN" ]; then
            green_echo "================================================"
            green_echo "Teamspeak 3 服务器安装完成！"
            green_echo "管理员令牌: $ADMIN_TOKEN"
            green_echo "请妥善保存此令牌，首次连接服务器时需要！"
            green_echo "================================================"
            
            # 保存密钥到文件
            echo "Teamspeak 3 管理员令牌: $ADMIN_TOKEN" | tee "$TS3_INSTALL_DIR/admin_token.txt" > /dev/null
            chown "$TS3_USER:$TS3_USER" "$TS3_INSTALL_DIR/admin_token.txt"
            
            # 同时保存服务器管理员账户信息
            SERVERADMIN_PASSWORD=$(sudo journalctl -u teamspeak3.service --since "1 minute ago" --no-pager | grep -o "password=.*" | head -1 | cut -d'"' -f2)
            if [ -n "$SERVERADMIN_PASSWORD" ]; then
                echo "服务器管理员账户: serveradmin" | tee -a "$TS3_INSTALL_DIR/admin_token.txt"
                echo "服务器管理员密码: $SERVERADMIN_PASSWORD" | tee -a "$TS3_INSTALL_DIR/admin_token.txt"
                green_echo "服务器管理员账户信息也已保存"
            fi
        else
            yellow_echo "警告：无法获取管理员令牌。"
            yellow_echo "请检查日志文件: sudo journalctl -u teamspeak3.service -f"
        fi
        
        green_echo "Teamspeak 3 服务器已成功安装并启动！"
        green_echo "安装目录: $TS3_INSTALL_DIR"
        green_echo "服务状态: sudo systemctl status teamspeak3"
        green_echo "查看日志: sudo journalctl -u teamspeak3 -f"
    else
        red_echo "Teamspeak 3 服务启动失败！"
        echo "详细错误信息："
        sudo systemctl status teamspeak3.service --no-pager
        echo ""
        red_echo "请检查以下可能的问题："
        red_echo "1. 端口是否被占用"
        red_echo "2. 文件权限是否正确"
        red_echo "3. 是否已创建许可文件"
        red_echo "4. 查看详细日志: sudo journalctl -u teamspeak3.service -n 50"
        
        # 显示更详细的错误信息
        echo ""
        red_echo "调试信息："
        echo "工作目录: $TS3_INSTALL_DIR"
        echo "可执行文件: $TS3_INSTALL_DIR/ts3server"
        echo "许可文件: $TS3_INSTALL_DIR/.ts3server_license_accepted"
        echo "许可文件存在: $( [ -f "$TS3_INSTALL_DIR/.ts3server_license_accepted" ] && echo "是" || echo "否" )"
        echo "可执行文件权限: $(ls -la "$TS3_INSTALL_DIR/ts3server" 2>/dev/null || echo "文件不存在")"
        
        return 1
    fi

    # 清理临时文件
    rm -f "/tmp/$TS3_ZIP_FILE"
    
    green_echo "Teamspeak 3 服务器安装完成！"
}

# --- Teamspeak 3 服务器管理功能 ---
manage_teamspeak3_server() {
    TS3_INSTALL_DIR="$home_dir/teamspeak3"  # 更新为当前用户目录
    
    if [ ! -f "$TS3_INSTALL_DIR/ts3server" ]; then
        red_echo "未检测到 Teamspeak 3 服务器安装，请先安装！"
        return 1
    fi
    
    while true; do
        echo "============================================="
        echo "          Teamspeak 3 服务器管理"
        echo "============================================="
        echo "1. 启动 Teamspeak 3 服务"
        echo "2. 停止 Teamspeak 3 服务"
        echo "3. 重启 Teamspeak 3 服务"
        echo "4. 查看 Teamspeak 3 状态"
        echo "5. 查看管理员密钥"
        echo "6. 查看服务日志"
        echo "0. 返回主菜单"
        echo "============================================="
        read -p "请输入操作编号: " choice

        case $choice in
            1)
                echo "启动 Teamspeak 3 服务..."
                if sudo systemctl start teamspeak3.service; then
                    green_echo "Teamspeak 3 服务启动成功！"
                else
                    red_echo "Teamspeak 3 服务启动失败！"
                    sudo systemctl status teamspeak3.service --no-pager
                fi
                ;;
            2)
                echo "停止 Teamspeak 3 服务..."
                if sudo systemctl stop teamspeak3.service; then
                    green_echo "Teamspeak 3 服务已停止。"
                else
                    red_echo "停止 Teamspeak 3 服务失败！"
                fi
                ;;
            3)
                echo "重启 Teamspeak 3 服务..."
                if sudo systemctl restart teamspeak3.service; then
                    green_echo "Teamspeak 3 服务重启成功！"
                else
                    red_echo "Teamspeak 3 服务重启失败！"
                    sudo systemctl status teamspeak3.service --no-pager
                fi
                ;;
            4)
                echo "Teamspeak 3 服务状态："
                sudo systemctl status teamspeak3.service --no-pager
                ;;
            5)
                echo "正在查找管理员密钥..."
                if [ -f "$TS3_INSTALL_DIR/admin_token.txt" ]; then
                    green_echo "管理员密钥："
                    cat "$TS3_INSTALL_DIR/admin_token.txt"
                else
                    yellow_echo "未找到保存的管理员密钥文件。"
                    yellow_echo "尝试从日志中提取..."
                    
                    # 从日志中提取令牌
                    ADMIN_TOKEN=$(sudo journalctl -u teamspeak3.service --no-pager | grep -E "token=[A-Za-z0-9+/]+" | head -1 | sed 's/.*token=//')
                    
                    if [ -z "$ADMIN_TOKEN" ]; then
                        # 如果第一次尝试失败，使用更宽松的匹配
                        ADMIN_TOKEN=$(sudo journalctl -u teamspeak3.service --no-pager | grep -o "token=[^ ]*" | head -1 | cut -d'=' -f2)
                    fi
                    
                    if [ -n "$ADMIN_TOKEN" ]; then
                        green_echo "管理员令牌: $ADMIN_TOKEN"
                        # 保存密钥到文件
                        echo "Teamspeak 3 管理员令牌: $ADMIN_TOKEN" | tee "$TS3_INSTALL_DIR/admin_token.txt" > /dev/null
                        chown "$REAL_user:$REAL_user" "$TS3_INSTALL_DIR/admin_token.txt"
                        
                        # 同时保存服务器管理员账户信息
                        SERVERADMIN_PASSWORD=$(sudo journalctl -u teamspeak3.service --no-pager | grep -o "password=.*" | head -1 | cut -d'"' -f2)
                        if [ -n "$SERVERADMIN_PASSWORD" ]; then
                            echo "服务器管理员账户: serveradmin" | tee -a "$TS3_INSTALL_DIR/admin_token.txt"
                            echo "服务器管理员密码: $SERVERADMIN_PASSWORD" | tee -a "$TS3_INSTALL_DIR/admin_token.txt"
                            green_echo "服务器管理员账户信息也已保存"
                        fi
                    else
                        red_echo "无法找到管理员令牌。"
                        yellow_echo "请检查服务是否正常运行，并查看日志文件。"
                    fi
                fi
                ;;
            6)
                echo "查看 Teamspeak 3 服务日志..."
                sudo journalctl -u teamspeak3.service -n 50 --no-pager
                echo ""
                yellow_echo "实时查看日志: sudo journalctl -u teamspeak3.service -f"
                ;;
            0)
                return 0
                ;;
            *)
                echo "无效的选择，请重新输入！"
                ;;
        esac
        echo ""
        read -p "按回车键继续..."
    done
}

# 检查Teamspeak3服务器是否已安装
check_teamspeak3_exist() {
    if [ -f "$home_dir/teamspeak3/ts3server" ]; then
        echo "检测到Teamspeak3服务器文件"
        return 0
    else
        return 1
    fi
}

# 修改hosts文件以优化大厅连接
modify_hosts_for_lobby() {
    echo "====== 修改hosts文件优化大厅连接 ======"
    yellow_echo "本功能适用于修改饥荒大厅连接，不了解用途请不要随意修改！"
    if ! ask_yes_no "确定要继续吗？" "N"; then
        echo "已取消修改hosts文件。"
        return 0
    fi

    # 定义要测试的IP地址
    ip1="168.138.199.234"
    ip2="132.145.125.18"
    domain="lobby-v2.klei.com"
    hosts_file="/etc/hosts"

    # 测试第一个IP的延迟
    echo "正在测试 $ip1 的延迟..."
    ping1=$(ping -c 3 -W 2 $ip1 | grep 'rtt' | awk -F '/' '{print $5}')
    if [ -z "$ping1" ]; then
        ping1=9999  # 无法连接时设置一个大值
        red_echo "$ip1 无法连接"
    else
        green_echo "$ip1 的平均延迟为: $ping1 ms"
    fi

    # 测试第二个IP的延迟
    echo "正在测试 $ip2 的延迟..."
    ping2=$(ping -c 3 -W 2 $ip2 | grep 'rtt' | awk -F '/' '{print $5}')
    if [ -z "$ping2" ]; then
        ping2=9999  # 无法连接时设置一个大值
        red_echo "$ip2 无法连接"
    else
        green_echo "$ip2 的平均延迟为: $ping2 ms"
    fi

    # 选择延迟较低的IP
    if (( $(echo "$ping1 < $ping2" | bc -l) )); then
        selected_ip=$ip1
        green_echo "选择 $selected_ip 作为连接地址（延迟较低）"
    else
        selected_ip=$ip2
        green_echo "选择 $selected_ip 作为连接地址（延迟较低）"
    fi

    # 备份hosts文件
    echo "备份当前hosts文件..."
    sudo cp $hosts_file ${hosts_file}.bak.$(date +%Y%m%d%H%M%S)

    # 移除已有的相关条目
    echo "清理已有的相关hosts条目..."
    sudo sed -i "/$domain/d" $hosts_file

    # 查找IPv6配置的起始行
    ipv6_start_line=$(sudo grep -n '^# The following lines are desirable for IPv6' $hosts_file | cut -d: -f1)

    if [ -n "$ipv6_start_line" ]; then
        # 在IPv6配置前插入新条目
        echo "在IPv6配置前插入新条目..."
        sudo sed -i "${ipv6_start_line}i ${selected_ip} ${domain}" $hosts_file
    else
        # 如果未找到IPv6配置，追加到文件末尾
        echo "未找到IPv6配置，追加新条目到文件末尾..."
        echo "${selected_ip} ${domain}" | sudo tee -a $hosts_file > /dev/null
    fi

    green_echo "hosts文件修改完成！已将 $domain 指向 $selected_ip 大厅地址提交网站：https://server.dstapi.com/server/"
    yellow_echo "如果需要恢复，请使用vi编辑备份文件: vi ${hosts_file}.bak.$(date +%Y%m%d%H%M%S)"
}

# 版本配置
versions=("多层版本" "多房间版本")
urls=(
    "http://47.108.31.40:5244/d/myfiles/dst-admin-go.1.5.2.tar.gz?sign=pn0pncrUMBHtSQE_qKO2fwSjZ3xn3SkwuQT-PKUQyXU=:0"
    "http://47.108.31.40:5244/d/myfiles/dst-admin-go-2.4.0-beta.tar.gz?sign=LYJN0Klv3gZ_vbS-Q0dZ58IUKcoAaWzBrbcSI7ewLgU=:0"
)

# 主安装流程
main_installation() {
    # 创建目录
    mkdir -p "$manual_dir" || {
        echo "目录创建失败: $manual_dir"
        exit 1
    }

    # 版本选择
    echo "请选择安装版本："
    PS3="输入数字选择："
    select num in "${versions[@]}" "取消"; do
        case $REPLY in
            1|2)
                selected=$((REPLY-1))
                break
                ;;
            3)
                echo "安装已取消"
                exit 0
                ;;
            *)
                echo "无效选择！"
                ;;
        esac
    done

    # 安装依赖
    install_dependencies
    
    # 创建必要的文件夹
    create_necessary_dirs
    
    # 检查SteamCMD和饥荒服务器是否已存在
    local steamcmd_exists=0
    local dst_server_exists=0
    
    if [ -d "$steamcmd_dir" ]; then
        steamcmd_exists=1
        echo "检测到已存在SteamCMD目录: $steamcmd_dir"
    fi
    
    if [ -d "$home_dir/dst-dedicated-server" ]; then
        dst_server_exists=1
        echo "检测到已存在饥荒服务器目录: $home_dir/dst-dedicated-server"
    fi
    
    # 根据检测结果决定是否安装
    if [ $steamcmd_exists -eq 1 ] && [ $dst_server_exists -eq 1 ]; then
        yellow_echo "SteamCMD和饥荒服务器均已存在，跳过安装步骤"
    else
        if [ $steamcmd_exists -eq 1 ]; then
            yellow_echo "SteamCMD已存在，但饥荒服务器不存在"
        elif [ $dst_server_exists -eq 1 ]; then
            yellow_echo "饥荒服务器已存在，但SteamCMD不存在"
        fi
        
        if ask_yes_no "是否安装缺失的SteamCMD和饥荒服务器组件？" "Y"; then
            install_steamcmd_and_dst
        else
            red_echo "警告：缺少必要的组件，可能导致面板无法正常工作"
        fi
    fi

    # 下载处理
    filename=$(basename "${urls[$selected]%%\?*}")
    local max_download_attempts=3
    local download_attempt=1
    
    # 检查文件是否存在或需要重新下载
    while [ $download_attempt -le $max_download_attempts ]; do
        if [ ! -f "$manual_dir/$filename" ] || [ $(stat -c%s "$manual_dir/$filename" 2>/dev/null || echo 0) -lt 102400 ]; then
            echo "正在下载 ${versions[$selected]} (尝试 $download_attempt/$max_download_attempts)..."
            if wget --progress=bar:force --limit-rate=2M -O "$manual_dir/$filename" "${urls[$selected]}"; then
                # 验证文件大小
                if [ $(stat -c%s "$manual_dir/$filename") -lt 102400 ]; then
                    red_echo "下载的文件过小，可能不完整"
                    rm -f "$manual_dir/$filename"
                    download_attempt=$((download_attempt + 1))
                    continue
                fi
                break
            else
                red_echo "下载失败，错误代码：$?"
                rm -f "$manual_dir/$filename"
                download_attempt=$((download_attempt + 1))
            fi
        else
            echo "使用已存在的安装包: $manual_dir/$filename"
            break
        fi
    done
    
    if [ $download_attempt -gt $max_download_attempts ]; then
        red_echo "超过最大下载尝试次数，安装失败"
        exit 1
    fi

    # 解压安装
    temp_dir=$(mktemp -d)
    echo "解压到临时目录: $temp_dir"
    
    # 使用新的解压函数，带重试机制
    if ! extract_file "$manual_dir/$filename" "$temp_dir"; then
        red_echo "解压失败！错误代码：$?"
        rm -rf "$temp_dir"
        
        # 提供手动解决选项
        yellow_echo "您可以尝试手动解压："
        yellow_echo "tar -xzvf $manual_dir/$filename -C $temp_dir --exclude=\"._*\" --exclude=\".DS_Store\""
        read -p "是否要手动处理并继续？(y/N): " manual_confirm
        if [[ $manual_confirm =~ ^[Yy]$ ]]; then
            echo "请手动执行上述命令，完成后按回车键继续..."
            read -p "手动操作已完成？(按回车继续): "
        else
            exit 1
        fi
    fi

    src_dir=$(find "$temp_dir" -maxdepth 1 -type d -name "dst-admin-go*" | head -1)
    [ -z "$src_dir" ] && {
        echo "无效的安装包结构！目录内容："
        ls -l "$temp_dir"
        exit 1
    }

    echo "安装文件到 $dest_dir..."
    mkdir -p "$dest_dir"
    cp -vr "$src_dir"/* "$dest_dir/"

    # 如果是多层版本，修改配置文件
    if [ $selected -eq 0 ]; then
        modify_dst_config
    fi

    # 增强权限设置
    echo "设置文件权限..."
    sudo chown -R $REAL_user:$REAL_user "$dest_dir"
    
    # 设置目录权限
    sudo find "$dest_dir" -type d -exec chmod 775 {} \;
    
    # 设置文件权限（保留可执行权限）
    sudo find "$dest_dir" -type f -exec chmod 664 {} \;
    
    # 特别设置可执行文件权限
    for exec_file in "$dest_dir"/dst-admin-go "$dest_dir"/*.sh; do
        if [ -f "$exec_file" ]; then
            sudo chmod +x "$exec_file"
            echo "设置可执行权限: $exec_file"
        fi
    done

    # 服务配置增强版 - 使用root用户确保权限
    configure_service() {
        service_file="/usr/lib/systemd/system/dst-admin-go.service"
        
        echo "生成服务配置文件..."
        sudo tee "$service_file" >/dev/null <<EOF
[Unit]
Description=DST Admin Go Service
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=$dest_dir
ExecStart=$dest_dir/dst-admin-go
Restart=always
RestartSec=30
Environment="PATH=$PATH:/usr/local/bin:/usr/bin:/bin"

[Install]
WantedBy=multi-user.target
EOF

        # 验证服务文件
        if ! sudo test -f "$service_file"; then
            echo "服务文件创建失败！"
            return 1
        fi

        # 权限设置
        sudo chmod 644 "$service_file"
        
        # 重载配置
        for i in {1..3}; do
            sudo systemctl daemon-reload && break
            sleep $i
        done

        # 启用服务
        sudo systemctl enable dst-admin-go.service
        
        # 启动服务
        sudo systemctl restart dst-admin-go.service
        sleep 5
        
        # 验证服务状态
        if ! systemctl is-active dst-admin-go.service >/dev/null; then
            echo "服务启动失败！错误日志："
            journalctl -u dst-admin-go.service -n 20 --no-pager
            return 1
        fi
    }

    # 执行服务配置
    if ! configure_service; then
        echo "服务配置失败！请手动检查："
        echo "1. 使用vi检查服务文件: vi $service_file"
        echo "2. 手动重载配置: sudo systemctl daemon-reload"
        echo "3. 查看服务状态: systemctl status dst-admin-go.service"
        exit 1
    fi

    # 首次安装虚拟内存设置（添加跳过选项）
    echo "====== 首次安装，配置虚拟内存 ======"
    yellow_echo "建议设置虚拟内存以提升服务器性能，特别是内存较小的服务器"
    if ask_yes_no "是否现在设置虚拟内存？" "Y"; then
        set_swap_memory
    else
        echo "已跳过虚拟内存设置，您可以在主菜单中手动设置"
    fi

    echo "面板安装完成！"
    echo "访问地址：http://$(curl -s ifconfig.me):8082"
    echo "如果使用nat服请修改8082对应的端口号 游戏端口号记得打开哦"
    echo "饥荒开荒和开服交流群737331541"
    echo "需要使用其他功能请重新运行脚本"
    echo "面板作者项目地址https://github.com/carrot-hu23/dst-admin-go"
    echo "面板作者反馈群863437190"
}

# 更新面板功能
update_panel() {
    echo "=== 面板更新 ==="
    
    # 更安全的服务停止
    if ! sudo systemctl stop dst-admin-go.service; then
        echo "警告：停止服务失败（可能服务未运行），继续更新..."
    fi

    # 目录处理
    pushd "$manual_dir" >/dev/null
    files=($(ls -t *.tar.gz *.tgz 2>/dev/null))
    [ ${#files[@]} -eq 0 ] && {
        echo "未找到更新文件！请将更新包放入 $manual_dir"
        popd >/dev/null
        return 1
    }

    # 文件选择
    local retry=0
    while true; do
        echo "可用的更新包："
        PS3="请输入数字选择更新包（最多错误3次）: "
        select file in "${files[@]}" "取消"; do
            case $REPLY in
                [1-9]*)
                    if (( REPLY > ${#files[@]} + 1 )); then
                        ((retry++))
                        echo "无效选择，剩余重试次数：$((3-retry))"
                        if (( retry >= 3 )); then
                            echo "错误次数过多，返回主菜单。"
                            popd >/dev/null
                            return 1
                        fi
                        continue
                    fi
                    if [[ "$file" == "取消" ]]; then
                        echo "操作已取消。"
                        popd >/dev/null
                        return 1
                    fi
                    break 2
                    ;;
                *)
                    ((retry++))
                    echo "无效输入，剩余重试次数：$((3-retry))"
                    if (( retry >= 3 )); then
                        echo "错误次数过多，返回主菜单。"
                        popd >/dev/null
                        return 1
                    fi
                    ;;
            esac
        done
    done
    popd >/dev/null

    # 增强解压验证
    temp_dir=$(mktemp -d)
    echo "正在验证更新包..."
    if ! tar -tzf "$manual_dir/$file" >/dev/null; then
        red_echo "更新包损坏！尝试重新下载..."
        rm -f "$manual_dir/$file"
        
        # 提示用户重新下载
        read -p "是否要重新下载该更新包？(y/N): " redownload
        if [[ $redownload =~ ^[Yy]$ ]]; then
            echo "请重新下载更新包并放置到 $manual_dir 后再试"
            rm -rf "$temp_dir"
            return 1
        else
            rm -rf "$temp_dir"
            return 1
        fi
    fi
    
    # 使用新的解压函数
    echo "正在解压更新包到 $temp_dir..."
    if ! extract_file "$manual_dir/$file" "$temp_dir"; then
        red_echo "解压失败！错误码：$?"
        rm -rf "$temp_dir"
        return 1
    fi

    src_dir=$(find "$temp_dir" -maxdepth 1 -type d -name "dst-admin-go*" | head -1)
    [ -z "$src_dir" ] && {
        echo "无效的更新包结构！目录内容："
        tree -L 2 "$temp_dir"
        rm -rf "$temp_dir"
        return 1
    }

    # 用户确认
    read -p "确认更新？将替换程序文件但保留配置 [y/N]: " confirm
    [[ $confirm =~ ^[Yy] ]] || { 
        rm -rf "$temp_dir"
        return 0
    }

    # 精确文件替换
    echo "开始安全更新..."
    required_files=(
        "dst-admin-go" 
        "start.sh" 
        "更新内容.txt" 
        "dist" 
        "static" 
        "version.txt"
    )
    exclude_files=("config" "worlds")

    for item in "${required_files[@]}"; do
        if [[ " ${exclude_files[@]} " =~ " ${item} " ]]; then
            echo "跳过保留项: $item"
            continue
        fi
        
        if [ -e "$dest_dir/$item" ]; then
            echo "移除旧文件: $dest_dir/$item"
            rm -rf "$dest_dir/$item"
        fi
        
        if [ -e "$src_dir/$item" ]; then
            echo "安装新文件: $item"
            cp -vr "$src_dir/$item" "$dest_dir/"
        fi
    done

    # 权限修复
    sudo chown -R $REAL_user:$REAL_user "$dest_dir"
    sudo find "$dest_dir" -type d -exec chmod 775 {} \;
    sudo find "$dest_dir" -type f -exec chmod 664 {} \;
    sudo chmod +x "$dest_dir/dst-admin-go" "$dest_dir/start.sh"

    # 服务重启
    sudo systemctl daemon-reload
    sudo systemctl start dst-admin-go.service
    sleep 5
    
    # 启动状态检查
    if ! systemctl is-active dst-admin-go.service >/dev/null; then
        echo "紧急错误：服务无法启动！"
        echo "可能原因："
        echo "1. 文件权限问题 → 检查 chmod +x 设置"
        echo "2. 版本不兼容 → 使用vi查看更新内容.txt"
        echo "3. 查看详细日志：journalctl -u dst-admin-go.service -n 50"
        rm -rf "$temp_dir"
        exit 1
    fi

    # 清理临时文件
    rm -rf "$temp_dir"
    
    echo "更新成功完成！请强制刷新浏览器缓存（Ctrl+F5）"
    echo "访问地址：http://$(curl -s ifconfig.me):8082"
    echo "如果使用nat服请修改8082对应的端口号 游戏端口号记得打开哦"
    echo "饥荒开荒和开服交流群737331541"
    echo "面板作者项目地址https://github.com/carrot-hu23/dst-admin-go"
    echo "面板作者反馈群863437190"
}

# 主流程
init_logging
debug_info

# 检查面板是否存在
if check_panel_exist; then
    echo "=== 检测到已安装面板 ==="
    
    # 检查饥荒服务器是否存在
    if check_dst_server_exist; then
        echo "=== 检测到已安装饥荒服务器 ==="
		echo "=== dst-admin-go饥荒面板多功能安装脚本 v5.2 ==="
		echo "===  脚本来自 伶依nekochan 抖音 ACFUN同名主播 ==="
        
        # 显示完整功能菜单
        while true; do
            PS3="请输入数字选择操作："
            select action in \
                "更新游戏服务器" \
                "更新管理面板" \
                "下载或者更新测试服" \
                "服务器性能测试" \
                "面板服务管理" \
                "LuaJIT性能优化模块管理（小白不懂不要装）" \
                "安装Teamspeak 3语音服务器" \
                "Teamspeak 3服务器管理" \
                "安装FRP客户端" \
                "FRP自动映射端口管理功能" \
                "MOD下载修复功能(建议优先运行一次)" \
                "更换APT软件源" \
                "设置系统虚拟内存" \
                "重装面板或者游戏服务器（会清空面板和游戏服务器和LuaJIT 不会影响存档）" \
                "修改Hosts优化大厅连接(需要提交到网页)" \
                "退出脚本"; do
                case $REPLY in
                    1)
                        echo "=== 更新游戏服务器 ==="
                        steamcmd_path="$steamcmd_dir/steamcmd.sh"  
                        if [ ! -f "$steamcmd_path" ]; then
                            echo "未找到steamcmd，请先通过安装面板安装！"
                            read -p "按回车返回主菜单..."
                            break
                        fi
                        
                        echo "正在更新饥荒正式服..."
                        cd "$steamcmd_dir" && \
                        ./steamcmd.sh +login anonymous \
                        +force_install_dir "$home_dir/dst-dedicated-server" \
                        +app_update 343050 validate +quit
                        
                        echo "更新完成！安装目录：$home_dir/dst-dedicated-server"
                        read -p "按回车返回主菜单..."
                        break
                        ;;
                    2)
                        echo "##########################################################"
                        echo "# 重要提示！更新面板需要先上传压缩包到dst/手动上传文件夹！"
                        echo "# 不是稳定版可能会有未知bug 可能无法正常使用！"
                        echo "# 请前往交流群或项目地址获取最新版本或者稳定版！"
                        echo "##########################################################"
                        read -p "按回车键继续更新（若确定要继续）或 Ctrl+C 取消..."
                        update_panel
                        read -p "按回车返回主菜单或输入q退出..." -t 60 input
                        [[ "$input" =~ [qQ] ]] && exit 0
                        break
                        ;;
                    3)
                        echo "##########################################################"
                        echo "# 重要提示！测试服功能需要面板1.5版本以上支持！"
                        echo "# 如果当前版本低于1.5，测试服可能无法正常使用！"
                        echo "# 请前往交流群或项目地址获取最新版本！"
                        echo "##########################################################"
                        read -p "按回车键继续下载（若确定要继续）或 Ctrl+C 取消..."

                        steamcmd_path="$steamcmd_dir/steamcmd.sh"  
                        if [ ! -f "$steamcmd_path" ]; then
                            echo "未找到steamcmd，请先通过更新游戏服务器安装！"
                            read -p "按回车返回主菜单..."
                            break
                        fi
                        
                        echo "正在下载饥荒测试服..."
                        cd "$steamcmd_dir" && \
                        ./steamcmd.sh +login anonymous \
                        +force_install_dir "$home_dir/dst-dedicated-server-beta" \
                        +app_update 343050 -beta updatebeta validate +quit
                        
                        echo "测试服下载完成！安装目录：$home_dir/dst-dedicated-server-beta 需要开服请到面板切换测试服"
                        read -p "按回车返回主菜单..."
                        break
                        ;;
                    4)
                        run_benchmark
                        read -p "按回车返回主菜单..."
                        break
                        ;;
                    5)
                        manage_panel_service
                        break
                        ;;
                    6)
                        echo "=== LuaJIT性能优化模块管理 ==="
                        manage_luajit
                        break
                        ;;
                    7)
                        echo "=== 安装Teamspeak 3语音服务器 ==="
                        install_teamspeak3_server
                        read -p "按回车返回主菜单..."
                        break
                        ;;
                    8)
                        echo "=== Teamspeak 3服务器管理 ==="
                        manage_teamspeak3_server
                        break
                        ;;
                    9)
                        install_frp_client
                        read -p "按回车返回主菜单..."
                        break
                        ;;
                    10)
                        auto_map_ports
                        read -p "按回车返回主菜单..."
                        break
                        ;;
                    11)
                        fix_mod_download
                        read -p "按回车返回主菜单..."
                        break
                        ;;
                    12)
                        echo "=== 更换APT软件源 ==="
                        change_apt_source
                        read -p "按回车返回主菜单..."
                        break
                        ;;
                    13)
                        set_swap_memory
                        read -p "按回车返回主菜单..."
                        break
                        ;;
                    14)
                        reinstall_menu
                        read -p "按回车返回主菜单..."
                        break
                        ;;
                    15)
                        modify_hosts_for_lobby
                        read -p "按回车返回主菜单..."
                        break
                        ;;
                    16)
                        echo "正在退出脚本...感谢使用"
                        exit 0
                        ;;
                    *)
                        if (( REPLY > 16 )); then
                            echo "输入错误次数过多，自动退出。"
                            exit 1
                        fi
                        echo "无效的选项，请重新输入数字！"
                        ;;
                esac
            done
        done
    else
        echo "=== 检测到面板已安装，但饥荒服务器未安装 ==="
        read -p "是否现在安装饥荒服务器？(y/N): " install_dst
        if [[ $install_dst =~ ^[Yy]$ ]]; then
            install_dependencies
            create_necessary_dirs
            install_steamcmd_and_dst
            read -p "饥荒服务器安装完成！按回车返回主菜单..."
        else
            echo "退出脚本。"
            exit 0
        fi
    fi
else
    echo "=== 开始全新安装 ==="
    # 首次运行，执行换源和时区设置
    yellow_echo "首次运行脚本，将执行必要的系统配置..."
    change_apt_source
    set_timezone
    install_dependencies
    main_installation
fi

echo "安装日志已保存至：$log_file"