#!/bin/bash
#
# #-----------------------------------------------------------#
# |   LBench 服务器测试工具   LemonBench Server Test Toolkit   |
# #-----------------------------------------------------------#
# | Written by iLemonrain <ilemonrain@ilemonrain.com>         |
# | My Blog: https://ilemonrain.com                           |
# | Telegram: https://t.me/ilemonrain                         |
# | Telegram (For +86 User): https://t.me/ilemonrain_chatbot  |
# | Telegram Channel: https://t.me/ilemonrain_channel         |
# #-----------------------------------------------------------#
#

# 全局定义

# 字体颜色定义
Font_Black="\033[30m"  
Font_Red="\033[31m" 
Font_Green="\033[32m"  
Font_Yellow="\033[33m"  
Font_Blue="\033[34m"  
Font_Purple="\033[35m"  
Font_SkyBlue="\033[36m"  
Font_White="\033[37m" 
Font_Suffix="\033[0m"

# ============================================

# 全局模块
Global_StartupInit() {
    # 清理残留，为新一次的运行做好准备
    rm -rf /tmp/.LBench_tmp
    rm -rf /.tmp_LBench/
}

# 功能模块
SystemInfo_GetHostname() {
    LBench_Result_Hostname="$(hostname)"
}

SystemInfo_GetCPUInfo() {
    mkdir -p /tmp/.LBench_tmp/data >/dev/null 2>&1
    cat /proc/cpuinfo > /tmp/.LBench_tmp/data/cpuinfo
    local ReadCPUInfo="cat /tmp/.LBench_tmp/data/cpuinfo"
    LBench_Result_CPUModelName="$($ReadCPUInfo | awk -F ': ' '/model name/{print $2}' | sort -u)"
    LBench_Result_CPUCacheSize="$($ReadCPUInfo | awk -F ': ' '/cache size/{print $2}' | sort -u)"
    LBench_Result_CPUPhysicalNumber="$($ReadCPUInfo | awk -F ': ' '/physical id/{print $2}' | sort -u | wc -l)"
    LBench_Result_CPUCoreNumber="$($ReadCPUInfo | awk -F ': ' '/cpu cores/{print $2}' | sort -u)"
    LBench_Result_CPUThreadNumber="$($ReadCPUInfo | awk -F ': ' '/cores/{print $2}' | wc -l)"
}

SystemInfo_GetMemInfo(){
    mkdir -p /tmp/.LBench_tmp/data >/dev/null 2>&1
    cat /proc/meminfo > /tmp/.LBench_tmp/data/meminfo
    local ReadMemInfo="cat /tmp/.LBench_tmp/data/meminfo"
    # 获取总内存
    LBench_Result_MemoryTotal_KB="$($ReadMemInfo | awk '/MemTotal/{print $2}')"
    LBench_Result_MemoryTotal_MB="$(echo $LBench_Result_MemoryTotal_KB | awk '{printf "%.2f\n",$1/1024}')"
    LBench_Result_MemoryTotal_GB="$(echo $LBench_Result_MemoryTotal_KB | awk '{printf "%.2f\n",$1/1048576}')"
    # 获取可用内存
    local MemFree="$($ReadMemInfo | awk '/MemFree/{print $2}')"
    local Buffers="$($ReadMemInfo | awk '/Buffers/{print $2}')"
    local Cached="$($ReadMemInfo | awk '/Cached/{print $2}')"
    LBench_Result_MemoryFree_KB="$(echo $MemFree $Buffers $Cached | awk '{printf $1+$2+$3}')"
    LBench_Result_MemoryFree_MB="$(echo $LBench_Result_MemoryFree_KB | awk '{printf "%.2f\n",$1/1024}')"
    LBench_Result_MemoryFree_GB="$(echo $LBench_Result_MemoryFree_KB | awk '{printf "%.2f\n",$1/1048576}')"
    # 获取已用内存
    local MemUsed="$(echo $LBench_Result_MemoryTotal_KB $LBench_Result_MemoryFree_KB | awk '{printf $1-$2}' )"
    LBench_Result_MemoryUsed_KB="$MemUsed"
    LBench_Result_MemoryUsed_MB="$(echo $LBench_Result_MemoryUsed_KB | awk '{printf "%.2f\n",$1/1024}')"
    LBench_Result_MemoryUsed_GB="$(echo $LBench_Result_MemoryUsed_KB | awk '{printf "%.2f\n",$1/1048576}')"
    # 获取Swap总量
    LBench_Result_SwapTotal_KB="$($ReadMemInfo | awk '/SwapTotal/{print $2}')"
    LBench_Result_SwapTotal_MB="$(echo $LBench_Result_SwapTotal_KB | awk '{printf "%.2f\n",$1/1024}')"
    LBench_Result_SwapTotal_GB="$(echo $LBench_Result_SwapTotal_KB | awk '{printf "%.2f\n",$1/1048576}')"
    # 获取可用Swap
    LBench_Result_SwapFree_KB="$($ReadMemInfo | awk '/SwapTotal/{print $2}')"
    LBench_Result_SwapFree_MB="$(echo $LBench_Result_SwapFree_KB | awk '{printf "%.2f\n",$1/1024}')"
    LBench_Result_SwapFree_GB="$(echo $LBench_Result_SwapFree_KB | awk '{printf "%.2f\n",$1/1048576}')"
    # 获取已用Swap
    local SwapUsed="$(echo $LBench_Result_SwapTotal_KB $LBench_Result_SwapFree_KB | awk '{printf $1-$2}')"
    LBench_Result_SwapUsed_KB="$SwapUsed"
    LBench_Result_SwapUsed_MB="$(echo $LBench_Result_SwapUsed_KB | awk '{printf "%.2f\n",$1/1024}')"
    LBench_Result_SwapUsed_GB="$(echo $LBench_Result_SwapUsed_KB | awk '{printf "%.2f\n",$1/1048576}')"
}

SystemInfo_GetOSRelease() {
    if [ -f "/etc/centos-release" ]; then    # CentOS
        Var_OSRelease="centos"
        local Var_OSReleaseFullName="$(cat /etc/os-release | awk -F '[= "]' '/PRETTY_NAME/{print $3,$4}')"
        local Var_OSReleaseVersion="$(cat /etc/centos-release | awk '{print $4}')"
        local Var_OSReleaseArch="$(arch)"
        LBench_Result_OSReleaseFullName="$Var_OSReleaseFullName $Var_OSReleaseVersion ($Var_OSReleaseArch)"
    elif [ -f "/etc/fedora-release" ]; then  # Fedora
        Var_OSRelease="fedora"
        local Var_OSReleaseFullName="$(cat /etc/os-release | awk -F '[= "]' '/PRETTY_NAME/{print $3}')"
        local Var_OSReleaseVersion="$(cat /etc/fedora-release | awk '{print $3,$4,$5,$6,$7}')"
        local Var_OSReleaseArch="$(arch)"
        LBench_Result_OSReleaseFullName="$Var_OSReleaseFullName $Var_OSReleaseVersion ($Var_OSReleaseArch)"
    elif [ -f "/etc/lsb-release" ]; then     # Ubuntu
        Var_OSRelease="ubuntu"
        local Var_OSReleaseFullName="$(cat /etc/os-release | awk -F '[= "]' '/NAME/{print $3}' | head -n1)"
        local Var_OSReleaseVersion="$(cat /etc/os-release | awk -F '[= "]' '/VERSION/{print $3,$4,$5,$6,$7}' | head -n1)"
        local Var_OSReleaseArch="$(arch)"
        LBench_Result_OSReleaseFullName="$Var_OSReleaseFullName $Var_OSReleaseVersion ($Var_OSReleaseArch)"
    elif [ -f "/etc/debian_version" ]; then  # Debian
        Var_OSRelease="debian"
        local Var_OSReleaseFullName="$(cat /etc/os-release | awk -F '[= "]' '/PRETTY_NAME/{print $3,$4}')"
        local Var_OSReleaseVersion="$(cat /etc/debian_version | awk '{print $1}')"
        local Var_OSReleaseArch="$(arch)"
        LBench_Result_OSReleaseFullName="$Var_OSReleaseFullName $Var_OSReleaseVersion ($Var_OSReleaseArch)"
    elif [ -f "/etc/alpine-release" ]; then  # Alpine Linux
        Var_OSRelease="alpinelinux"
        local Var_OSReleaseFullName="$(cat /etc/os-release | awk -F '[= "]' '/NAME/{print $3,$4}' | head -n1)"
        local Var_OSReleaseVersion="$(cat /etc/alpine-release | awk '{print $1}')"
        local Var_OSReleaseArch="$(arch)"
        LBench_Result_OSReleaseFullName="$Var_OSReleaseFullName $Var_OSReleaseVersion ($Var_OSReleaseArch)"
    else
        Var_OSRelease="unknown" # 未知系统分支
        LBench_Result_OSReleaseFullName="[Error: 未知系统分支 !]"
    fi
}

SystemInfo_GetVirtType() {
    if [ ! -f "/usr/sbin/virt-what" ]; then
        Var_VirtType="Unknown"
        LBench_Result_VirtType="[Error: 未安装virt-what !]"
    elif [ -f "/.dockerenv" ]; then # 处理Docker虚拟化
        Var_VirtType="docker"
        LBench_Result_VirtType="Docker"
    else # 正常判断流程
        Var_VirtType="$(virt-what)"
        local Var_VirtTypeCount="$(echo $Var_VirtTypeCount | wc -l)"
        if [ "$Var_VirtTypeCount" -ge "2" ]; then   # 处理嵌套虚拟化
            LBench_Result_VirtType="echo ${Var_VirtType} | tr '\n' ' '"
            Var_VirtType="$(echo $Var_VirtType | head -n1)" # 使用检测到的第一种虚拟化继续做判断
        elif [ "$Var_VirtTypeCount" -eq "1" ] && [ "$Var_VirtType" != "" ]; then # 只有一种虚拟化
            LBench_Result_VirtType="${Var_VirtType}"
        else
            local Var_BIOSVendor="$(dmidecode -s bios-vendor)"
            if [ "${Var_BIOSVendor}" = "SeaBIOS" ]; then
                Var_VirtType="Unknown"
                LBench_Result_VirtType="Unknown with SeaBIOS BIOS"
            else
                Var_VirtType="Dedicated"
                LBench_Result_VirtType="Dedicated with ${Var_BIOSVendor} BIOS"
            fi
        fi
    fi
}

SystemInfo_GetLoadAverage() {
    local Var_LoadAverage="$(cat /proc/loadavg)"
    LBench_Result_LoadAverage_1min="$(echo ${Var_LoadAverage} | awk '{print $1}')"
    LBench_Result_LoadAverage_5min="$(echo ${Var_LoadAverage} | awk '{print $2}')"
    LBench_Result_LoadAverage_15min="$(echo ${Var_LoadAverage} | awk '{print $3}')"
}

SystemInfo_GetDiskStat() {
    LBench_Result_DiskRootPath="$(df -x tmpfs / | awk 'NR==2 {print $1}')"
    local Var_DiskTotalSpace_KB="$(df -x tmpfs / | awk 'NR==2 {print $2}')"
    LBench_Result_DiskTotal_KB="${Var_DiskTotalSpace_KB}"
    LBench_Result_DiskTotal_MB="$(echo ${Var_DiskTotalSpace_KB} | awk '{printf "%.2f\n",$1/1000}')"
    LBench_Result_DiskTotal_GB="$(echo ${Var_DiskTotalSpace_KB} | awk '{printf "%.2f\n",$1/1000000}')"
    LBench_Result_DiskTotal_TB="$(echo ${Var_DiskTotalSpace_KB} | awk '{printf "%.2f\n",$1/1000000000}')"
    local Var_DiskUsedSpace_KB="$(df -x tmpfs / | awk 'NR==2 {print $3}')"
    LBench_Result_DiskUsed_KB="${Var_DiskUsedSpace_KB}"
    LBench_Result_DiskUsed_MB="$(echo ${LBench_Result_DiskUsed_KB} | awk '{printf "%.2f\n",$1/1000}')"
    LBench_Result_DiskUsed_GB="$(echo ${LBench_Result_DiskUsed_KB} | awk '{printf "%.2f\n",$1/1000000}')"
    LBench_Result_DiskUsed_TB="$(echo ${LBench_Result_DiskUsed_KB} | awk '{printf "%.2f\n",$1/1000000000}')"
    local Var_DiskFreeSpace_KB="$(df -x tmpfs / | awk 'NR==2 {print $4}')"
    LBench_Result_DiskFree_KB="${Var_DiskFreeSpace_KB}"
    LBench_Result_DiskFree_MB="$(echo ${LBench_Result_DiskFree_KB} | awk '{printf "%.2f\n",$1/1000}')"
    LBench_Result_DiskFree_GB="$(echo ${LBench_Result_DiskFree_KB} | awk '{printf "%.2f\n",$1/1000000}')"
    LBench_Result_DiskFree_TB="$(echo ${LBench_Result_DiskFree_KB} | awk '{printf "%.2f\n",$1/1000000000}')"
}

Function_GetSystemInfo() {
    Check_Virtwhat
    SystemInfo_GetCPUInfo
    SystemInfo_GetMemInfo
    SystemInfo_GetVirtType
    SystemInfo_GetOSRelease
    SystemInfo_GetDiskStat
    SystemInfo_GetLoadAverage
}

Function_ShowSystemInfo() {
    echo -e " ${Font_Yellow}系统名称:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_OSReleaseFullName}${Font_Suffix}"
    echo -e " ${Font_Yellow}CPU型号:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_CPUModelName}${Font_Suffix}"
    echo -e " ${Font_Yellow}CPU缓存大小:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_CPUCacheSize}${Font_Suffix}"
    # CPU数量 分支判断
    if [ "${Var_VirtType}" = "Dedicated" ]; then
        echo -e " ${Font_Yellow}CPU数量:${Font_Suffix}\t\t${LBench_Result_CPUPhysicalNumber} ${Font_SkyBlue}物理CPU${Font_Suffix}, ${LBench_Result_CPUCoreNumber} ${Font_SkyBlue}核心${Font_Suffix}, ${LBench_Result_CPUThreadNumber} ${Font_SkyBlue}线程${Font_Suffix}"
    elif [ "${Var_VirtType}" = "openvz" ]; then
        echo -e " ${Font_Yellow}CPU数量:${Font_Suffix}\t\t${LBench_Result_CPUThreadNumber} ${Font_SkyBlue}vCPU${Font_Suffix} (${LBench_Result_CPUCoreNumber} ${Font_SkyBlue}宿主机核心${Font_Suffix})"
    else
        echo -e " ${Font_Yellow}CPU数量:${Font_Suffix}\t\t${LBench_Result_CPUThreadNumber} ${Font_SkyBlue}vCPU${Font_Suffix}"
    fi
    echo -e " ${Font_Yellow}虚拟化类型:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_VirtType}${Font_Suffix}"
    # 内存使用率 分支判断
    if [ "${LBench_Result_MemoryUsed_KB}" -lt "1024" ] && [ "${LBench_Result_MemoryTotal_KB}" -lt "1048576" ]; then
        echo -e " ${Font_Yellow}内存使用率:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_MemoryUsed_MB} KB${Font_Suffix} / ${Font_SkyBlue}${LBench_Result_MemoryTotal_MB} MB${Font_Suffix}"
    elif [ "${LBench_Result_MemoryUsed_KB}" -lt "1048576" ] && [ "${LBench_Result_MemoryTotal_KB}" -lt "1048576" ]; then
        echo -e " ${Font_Yellow}内存使用率:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_MemoryUsed_MB} MB${Font_Suffix} / ${Font_SkyBlue}${LBench_Result_MemoryTotal_MB} MB${Font_Suffix}"
    elif [ "${LBench_Result_MemoryUsed_KB}" -lt "1048576" ] && [ "${LBench_Result_MemoryTotal_KB}" -lt "1073741824" ]; then
        echo -e " ${Font_Yellow}内存使用率:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_MemoryUsed_MB} MB${Font_Suffix} / ${Font_SkyBlue}${LBench_Result_MemoryTotal_GB} GB${Font_Suffix}"
    else
        echo -e " ${Font_Yellow}内存使用率:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_MemoryUsed_GB} GB${Font_Suffix} / ${Font_SkyBlue}${LBench_Result_MemoryTotal_GB} GB${Font_Suffix}"
    fi
    # Swap使用率 分支判断
    if [ "${LBench_Result_SwapTotal_KB}" -eq "0" ]; then
        echo -e " ${Font_Yellow}Swap使用率:${Font_Suffix}\t\t${Font_SkyBlue}[无Swap分区/文件]${Font_Suffix}"
    elif [ "${LBench_Result_SwapUsed_KB}" -lt "1024" ] && [ "${LBench_Result_SwapTotal_KB}" -lt "1048576" ]; then
        echo -e " ${Font_Yellow}Swap使用率:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_SwapUsed_KB} KB${Font_Suffix} / ${Font_SkyBlue}${LBench_Result_SwapTotal_MB} MB${Font_Suffix}"
    elif [ "${LBench_Result_SwapUsed_KB}" -lt "1024" ] && [ "${LBench_Result_SwapTotal_KB}" -lt "1073741824" ]; then
        echo -e " ${Font_Yellow}Swap使用率:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_SwapUsed_KB} KB${Font_Suffix} / ${Font_SkyBlue}${LBench_Result_SwapTotal_GB} GB${Font_Suffix}"
    elif [ "${LBench_Result_SwapUsed_KB}" -lt "1048576" ] && [ "${LBench_Result_SwapTotal_KB}" -lt "1048576" ]; then
        echo -e " ${Font_Yellow}Swap使用率:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_SwapUsed_MB} MB${Font_Suffix} / ${Font_SkyBlue}${LBench_Result_SwapTotal_MB} MB${Font_Suffix}"
    elif [ "${LBench_Result_SwapUsed_KB}" -lt "1048576" ] && [ "${LBench_Result_SwapTotal_KB}" -lt "1073741824" ]; then
        echo -e " ${Font_Yellow}Swap使用率:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_SwapUsed_MB} MB${Font_Suffix} / ${Font_SkyBlue}${LBench_Result_SwapTotal_GB} GB${Font_Suffix}"
    else
        echo -e " ${Font_Yellow}Swap使用率:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_SwapUsed_GB} GB${Font_Suffix} / ${Font_SkyBlue}${LBench_Result_SwapTotal_GB} GB${Font_Suffix}"
    fi
    # 启动磁盘
    echo -e "${Font_Yellow} 引导设备:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_DiskRootPath}${Font_Suffix}"
    # 磁盘使用率 分支判断
    if [ "${LBench_Result_DiskUsed_KB}" -lt "1000000" ]; then
        echo -e " ${Font_Yellow}磁盘使用率:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_DiskUsed_MB} MB${Font_Suffix} / ${Font_SkyBlue}${LBench_Result_DiskTotal_MB} MB${Font_Suffix}"
    elif [ "${LBench_Result_DiskUsed_KB}" -lt "1000000" ] && [ "${LBench_Result_DiskTotal_KB}" -lt "1000000000" ]; then
        echo -e " ${Font_Yellow}磁盘使用率:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_DiskUsed_MB} MB${Font_Suffix} / ${Font_SkyBlue}${LBench_Result_DiskTotal_GB} GB${Font_Suffix}"
    elif [ "${LBench_Result_DiskUsed_KB}" -lt "1000000000" ] && [ "${LBench_Result_DiskTotal_KB}" -lt "1000000000" ]; then
        echo -e " ${Font_Yellow}磁盘使用率:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_DiskUsed_GB} GB${Font_Suffix} / ${Font_SkyBlue}${LBench_Result_DiskTotal_GB} GB${Font_Suffix}"
    elif [ "${LBench_Result_DiskUsed_KB}" -lt "1000000000" ] && [ "${LBench_Result_DiskTotal_KB}" -ge "1000000000" ]; then
        echo -e " ${Font_Yellow}磁盘使用率:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_DiskUsed_GB} GB${Font_Suffix} / ${Font_SkyBlue}${LBench_Result_DiskTotal_TB} TB${Font_Suffix}"
    else
        echo -e " ${Font_Yellow}磁盘使用率:${Font_Suffix}\t\t${Font_SkyBlue}${LBench_Result_DiskUsed_TB} GB${Font_Suffix} / ${Font_SkyBlue}${LBench_Result_DiskTotal_TB} TB${Font_Suffix}"
    fi
    # 系统负载
    echo -e " ${Font_Yellow}系统负载(1/5/15min):${Font_Suffix}\t${Font_SkyBlue}${LBench_Result_LoadAverage_1min} ${LBench_Result_LoadAverage_5min} ${LBench_Result_LoadAverage_15min} ${Font_Suffix}"
}

# 网络测速模块
Run_Speedtest() {
    # 调用方式: Run_Speedtest "服务器ID" "节点名称(用于显示)"
    if [ -f "/usr/sbin/speedtest-cli" ]; then
        Speedtest_Exec="speedtest-cli"
    else
        Speedtest_Exec="speedtest"
    fi 
    echo -n -e " $2\c"
    Speedtest_Result_Ping=""
    Speedtest_Result_Download=""
    Speedtest_Result_Upload=""
    if [ "$1" = "default" ]; then
        local Speedtest_Result="$(${Speedtest_Exec} --simple --bytes)"
    else
        local Speedtest_Result="$(${Speedtest_Exec} --server $1 --simple --bytes)"
    fi
    Speedtest_Result_Ping="$(echo "${Speedtest_Result}" | awk '(NR==1){print $2}')"
    Speedtest_Result_Download="$(echo "${Speedtest_Result}" | awk '(NR==2){print $2}')"
    Speedtest_Result_Upload="$(echo "${Speedtest_Result}" | awk '(NR==3){print $2}')"
    echo -n -e "\r $2\t\t${Font_SkyBlue}${Speedtest_Result_Upload}${Font_Suffix} MB/s\t${Font_SkyBlue}${Speedtest_Result_Download}${Font_Suffix} MB/s\t${Font_SkyBlue}${Speedtest_Result_Ping}${Font_Suffix} ms\n"
}

Function_Speedtest_Fast() {
    Check_Speedtest
    echo -e " ${Font_Yellow}节点名称\t\t上传速度\t下载速度\tPing延迟${Font_Suffix}"
    Run_Speedtest "default" "距离最近测速点"
    Run_Speedtest "5145" "华北-北京联通"
    Run_Speedtest "16803" "华东-上海移动"
    Run_Speedtest "17251" "华南-广州电信"
}

Function_Speedtest_Full() {
    Check_Speedtest
    echo -e " ${Font_Yellow}节点名称\t\t上传速度\t下载速度\tPing延迟${Font_Suffix}"
    # 默认测试
    Run_Speedtest "default" "距离最近测速点"
    # ST测试
    Run_Speedtest "10392" "ST-美国洛杉矶"
    # 国内测试
    Run_Speedtest "5460" "东北-黑龙江联通"
    Run_Speedtest "16375" "东北-吉林移动"
    Run_Speedtest "5145" "华北-北京联通"
    Run_Speedtest "4713" "华北-北京移动"
    Run_Speedtest "13704" "华中-南京联通"
    Run_Speedtest "5396" "华中-苏州电信"
    Run_Speedtest "5083" "华东-上海联通"
    Run_Speedtest "16803" "华东-上海移动"
    Run_Speedtest "17251" "华南-广州电信"
    Run_Speedtest "6611" "华南-广州移动"
    Run_Speedtest "5103" "西南-昆明联通"
    Run_Speedtest "6168" "西南-昆明移动"
    Run_Speedtest "4946" "西北-兰州联通"
    Run_Speedtest "3973" "西北-兰州电信"
    Run_Speedtest "16145" "西北-兰州移动"
}

Run_DiskTest() {
    # 调用方式: Run_DiskTest "测试文件名" "块大小" "写入次数" "测试项目名称"
    # 将先测试读，后测试写
    # 避免磁盘压力过高，启动测试前暂停0.5秒
    mkdir -p /.tmp_LBench/DiskTest >/dev/null 2>&1
    mkdir -p /tmp/.LBench_tmp/data >/dev/null 2>&1
    local Var_DiskTestResultFile="/tmp/.LBench_tmp/data/disktest_result"
    echo -n -e " $4\c"
    # 清理缓存，避免影响测试结果
    sync
    echo 3 > /proc/sys/vm/drop_caches
    sleep 0.5
    # 正式写测试
    dd if=/dev/zero of=/.tmp_LBench/DiskTest/$1 bs=$2 count=$3 oflag=direct 2>${Var_DiskTestResultFile}
    DiskTest_WriteSpeed="$(cat ${Var_DiskTestResultFile} | awk '(NR==3){print $10,$11}')"
    DiskTest_WriteTime="$(cat ${Var_DiskTestResultFile} | awk '(NR==3){print $8}')"
    DiskTest_WriteIOPS="$(echo ${DiskTest_WriteTime} $3 | awk '{printf "%d\n",$2/$1}')"
    DiskTest_WritePastTime="$(echo ${DiskTest_WriteTime} | awk '{printf "%.2f\n",$1}')"
    echo -n -e "\r $4\t\t${Font_SkyBlue}${DiskTest_WriteSpeed} (${DiskTest_WriteIOPS} IOPS, ${DiskTest_WritePastTime}s)${Font_Suffix}\t\t\c"
    # 清理结果文件，准备下一次测试
    rm -f ${Var_DiskTestResultFile}
    # 清理缓存，避免影响测试结果
    sync
    echo 3 > /proc/sys/vm/drop_caches
    sleep 0.5
    # 正式读测试
    dd if=/.tmp_LBench/DiskTest/$1 of=/dev/null bs=$2 count=$3 iflag=direct 2>${Var_DiskTestResultFile}
    DiskTest_ReadSpeed="$(cat ${Var_DiskTestResultFile} | awk '(NR==3){print $10,$11}')"
    DiskTest_ReadTime="$(cat ${Var_DiskTestResultFile} | awk '(NR==3){print $8}')"
    DiskTest_ReadIOPS="$(echo ${DiskTest_ReadTime} $3 | awk '{printf "%d\n",$2/$1}')"
    DiskTest_ReadPastTime="$(echo ${DiskTest_ReadTime} | awk '{printf "%.2f\n",$1}')"
    rm -f ${Var_DiskTestResultFile}
    # 输出结果
    echo -n -e "\r $4\t\t${Font_SkyBlue}${DiskTest_WriteSpeed} (${DiskTest_WriteIOPS} IOPS, ${DiskTest_WritePastTime}s)${Font_Suffix}\t\t${Font_SkyBlue}${DiskTest_ReadSpeed} (${DiskTest_ReadIOPS} IOPS, ${DiskTest_ReadPastTime}s)${Font_Suffix}\n"
    rm -rf /.tmp_LBench/DiskTest/
}

Function_DiskTest_Fast() {
    echo -e " ${Font_Yellow}测试项目\t\t写入速度\t\t\t\t读取速度${Font_Suffix}"
    Run_DiskTest "100MB.test" "4k" "25600" "100MB-4K块"
    Run_DiskTest "1000MB.test" "1M" "1000" "1000MB-1M块"
}

Function_DiskTest_Full() {
    echo -e " ${Font_Yellow}测试项目\t\t写入速度\t\t\t\t读取速度${Font_Suffix}"
    Run_DiskTest "10MB.test" "4k" "2560" "10MB-4K块"
    Run_DiskTest "10MB.test" "1M" "10" "10MB-1M块"
    Run_DiskTest "100MB.test" "4k" "25600" "100MB-4K块"
    Run_DiskTest "100MB.test" "1M" "100" "100MB-1M块"
    Run_DiskTest "1000MB.test" "4k" "256000" "1000MB-4K块"
    Run_DiskTest "1000MB.test" "1M" "1000" "1000MB-1M块"
    Run_DiskTest "5000MB.test" "4k" "1280000" "5000MB-4K块"
    Run_DiskTest "5000MB.test" "1M" "5000" "5000MB-1M块"
}

Run_BestTrace() {
    # 调用方式: Run_BestTrace "目标IP" "ICMP/TCP" "最大跃点数" "说明"
    if [ "$2" = "tcp" ] || [ "$2" = "TCP" ]; then
        echo -e "路由追踪到 $4 (TCP 模式, 最大 $3 跃点)"
        echo -e "============================================================"
        besttrace -g cn -q 1 -T -m $3 $1
    else
        echo -e "路由追踪到 $4 (ICMP 模式, 最大 $3 跃点)"
        echo -e "============================================================"
        besttrace -g cn -q 1 -m $3 $1
    fi
}

Function_BestTrace_Full() {
    Check_BestTrace
    Run_BestTrace "123.125.115.110" "TCP" "30" "北京联通"
    Run_BestTrace "220.181.57.216" "TCP" "30" "北京电信"
    Run_BestTrace "221.176.60.132" "TCP" "30" "北京移动"

    Run_BestTrace "140.206.108.105" "TCP" "30" "上海联通"
    Run_BestTrace "101.95.225.213" "TCP" "30" "上海电信"
    Run_BestTrace "221.176.17.218" "TCP" "30" "上海移动"

    Run_BestTrace "219.158.19.66" "TCP" "30" "广州联通"
    Run_BestTrace "121.14.50.65" "TCP" "30" "广州电信"
    Run_BestTrace "221.176.20.14" "TCP" "30" "广州移动"
    # 美国部分
    Run_BestTrace "94.158.244.1" "TCP" "30" "美国俄勒冈-MivoCloud"
    Run_BestTrace "45.32.3.6" "TCP" "30" "美国新泽西-Vultr"
    Run_BestTrace "23.224.2.1" "TCP" "30" "美国洛杉矶-CeraNetworks"
    # 欧洲部分
    Run_BestTrace "84.200.17.1" "TCP" "30" "德国法兰克福-acclerated.de"
    Run_BestTrace "149.202.203.96" "TCP" "30" "法国OVH"
    Run_BestTrace "77.78.107.117" "TCP" "30" "捷克FinalTek"
    # 日本部分
    Run_BestTrace "210.140.10.72" "TCP" "30" "日本东京IDCF"
    Run_BestTrace "202.5.222.221" "TCP" "30" "日本大阪XTOM"
    Run_BestTrace "108.61.201.151" "TCP" "30" "日本东京Vultr"
    # 香港部分
    Run_BestTrace "112.120.90.254" "TCP" "30" "香港HKT"
    Run_BestTrace "61.238.140.253" "TCP" "30" "香港HKBN"
    Run_BestTrace "118.140.65.194" "TCP" "30" "香港HGC"
    # 台湾部分
    Run_BestTrace "61.223.94.3" "TCP" "30" "台湾CHT"
    Run_BestTrace "210.203.22.254" "TCP" "30" "台湾APTG"
    Run_BestTrace "175.98.163.72" "TCP" "30" "台湾TWMBroadBand"
    Run_BestTrace "103.51.140.1" "TCP" "30" "台湾Chief"
}

Function_SpooferTest() {
    Check_Spoofer
    echo -e "正在运行Spoofer测试，请耐心等待..."
    /usr/sbin/spoofer-prober -s0 -r0 > /tmp/spoofer.log
    if [ "$?" = "0" ]; then
        echo -e "\nSpoofer测试结果：$(cat /tmp/spoofer.log | awk '/https/{print $1}' | awk 'NR==2')"
    else
        echo -e "\nSpoofer测试失败! 请使用 cat /tmp/spoofer.log 查看日志!"
    fi
}

Check_Virtwhat() {
    if [ ! -f "/usr/sbin/virt-what" ]; then
        SystemInfo_GetOSRelease
        if [ "${Var_OSRelease}" = "centos" ]; then
            echo -e "${Msg_Warning}未检测到Virt-What模块，正在安装..."
            yum -y -q install virt-what
        elif [ "${Var_OSRelease}" = "ubuntu" ] || [ "${Var_OSRelease}" = "debian" ]; then
            echo -e "${Msg_Warning}未检测到Virt-What模块，正在安装..."
            apt-get install -y -qq virt-what
        elif [ "${Var_OSRelease}" = "fedora" ]; then
            echo -e "${Msg_Warning}未检测到Virt-What模块，正在安装..."
            dnf -y -q install virt-what
        elif [ "${Var_OSRelease}" = "alpinelinux" ]; then
            echo -e "${Msg_Warning}未检测到Virt-What模块，正在安装..."
            apk update -q
            apk add -q virt-what
        else
            echo -e "${Msg_Warning}未检测到Virt-What模块，但无法确定当前系统分支!"
        fi
    fi
    # 二次检测
    if [ ! -f "/usr/sbin/virt-what" ]; then
        echo -e "Virt-What模块安装失败! 请尝试重启程序或者手动安装!"
        exit 1
    fi
}

Check_Speedtest() {
    if [ ! -f "/usr/local/bin/speedtest" ] || [ ! -f "/usr/local/bin/speedtest-cli" ]; then
        SystemInfo_GetOSRelease
        if [ "${Var_OSRelease}" = "centos" ]; then
            echo -e "${Msg_Warning}未检测到Speedtest模块，正在安装..."
            yum -y -q install curl python
            curl https://bootstrap.pypa.io/get-pip.py -o /tmp/get-pip.py
            python /tmp/get-pip.py
            pip install speedtest-cli
            rm -f /tmp/get-pip.py
        elif [ "${Var_OSRelease}" = "ubuntu" ] || [ "${Var_OSRelease}" = "debian" ]; then
            echo -e "${Msg_Warning}未检测到Speedtest模块，正在安装..."
            apt-get --no-install-recommends -y install python-pip
            pip install -q speedtest-cli
        elif [ "${Var_OSRelease}" = "fedora" ]; then
            echo -e "${Msg_Warning}未检测到Speedtest模块，正在安装..."
            dnf -y -q install python-pip
            pip install -q speedtest-cli
        elif [ "${Var_OSRelease}" = "alpinelinux" ]; then
            echo -e "${Msg_Warning}未检测到Speedtest模块，正在安装..."
            apk update -q
            apk add -q py2-pip
            pip install -q speedtest-cli
        else
            echo -e "${Msg_Warning}未检测到Speedtest模块，但无法确定当前系统分支!"
        fi      
    fi
    # 二次检测
    if [ ! -f "/usr/local/bin/speedtest" ] || [ ! -f "/usr/local/bin/speedtest-cli" ]; then
        echo -e "Speedtest模块安装失败! 请尝试重启程序或者手动安装!"
        exit 1
    fi
}

Check_BestTrace() {
    if [ ! -f "/usr/sbin/besttrace" ]; then
        SystemInfo_GetOSRelease
        if [ "${Var_OSRelease}" = "centos" ]; then
            echo -e "${Msg_Warning}未检测到BestTrace模块，正在安装..."
            yum -y -q install curl unzip
            curl https://cdn.ipip.net/17mon/besttrace4linux.zip -o /tmp/besttrace.zip
            unzip -qo /tmp/besttrace.zip -d /tmp/besttrace/
            mv /tmp/besttrace/besttrace /usr/sbin/besttrace
            chmod +x /usr/sbin/besttrace
            rm -rf /tmp/besttrace*
        elif [ "${Var_OSRelease}" = "ubuntu" ] || [ "${Var_OSRelease}" = "debian" ]; then
            echo -e "${Msg_Warning}未检测到BestTrace模块，正在安装..."
            apt-get --no-install-recommends -y install wget unzip
            curl https://cdn.ipip.net/17mon/besttrace4linux.zip -o /tmp/besttrace.zip
            unzip -qo /tmp/besttrace.zip -d /tmp/besttrace/
            mv /tmp/besttrace/besttrace /usr/sbin/besttrace
            chmod +x /usr/sbin/besttrace
            rm -rf /tmp/besttrace*
        elif [ "${Var_OSRelease}" = "fedora" ]; then
            echo -e "${Msg_Warning}未检测到BestTrace模块，正在安装..."
            dnf -y -q install wget unzip
            curl https://cdn.ipip.net/17mon/besttrace4linux.zip -o /tmp/besttrace.zip
            unzip -qo /tmp/besttrace.zip -d /tmp/besttrace/
            mv /tmp/besttrace/besttrace /usr/sbin/besttrace
            chmod +x /usr/sbin/besttrace
            rm -rf /tmp/besttrace*
        elif [ "${Var_OSRelease}" = "alpinelinux" ]; then
            echo -e "${Msg_Warning}未检测到BestTrace模块，正在安装..."
            apk update -q
            apk add -q wget unzip
            curl https://cdn.ipip.net/17mon/besttrace4linux.zip -o /tmp/besttrace.zip
            unzip -qo /tmp/besttrace.zip -d /tmp/besttrace/
            mv /tmp/besttrace/besttrace /usr/sbin/besttrace
            chmod +x /usr/sbin/besttrace
            rm -rf /tmp/besttrace*
        else
            echo -e "${Msg_Warning}未检测到BestTrace模块，但无法确定当前系统分支!"
        fi
    fi
    # 二次检测
    if [ ! -f "/usr/sbin/besttrace" ]; then
        echo -e "BestTrace模块安装失败! 请尝试重启程序或者手动安装!"
        exit 1
    fi
}

Check_Spoofer() {
    if [ ! -f "/usr/sbin/spoofer-prober" ]; then
        if [ "${Var_OSRelease}" = "centos" ]; then
            echo -e "${Msg_Warning}未检测到Spoofer模块，正在安装..."
            yum install -q -y wget make gcc gcc-c++ traceroute openssl-devel protobuf-devel bison flex libpcap-devel
            mkdir -p /tmp/_LBench/src/
            mkdir -p /tmp/_LBench/bin/
            wget -qO /tmp/_LBench/src/spoofer.tar.gz https://www.caida.org/projects/spoofer/downloads/spoofer-1.4.2.tar.gz
            cd /tmp/_LBench/src/
            tar xvf spoofer.tar.gz && cd spoofer-1.4.2
            ./configure && make
            cp prober/spoofer-prober /usr/sbin/spoofer-prober
            cd /tmp && rm -rf /tmp/_LBench/src/spoofer* && rm -rf /tmp/_LBench/bin/spoofer*
        elif [ "${Var_OSRelease}" = "ubuntu" ] || [ "${Var_OSRelease}" = "debian" ]; then
            echo -e "${Msg_Warning}未检测到Spoofer模块，正在安装..."
            apt-get install -y --no-install-recommends traceroute protobuf-compiler libpcap-dev libprotobuf-dev
            mkdir -p /tmp/_LBench/src/
            mkdir -p /tmp/_LBench/bin/
            wget -qO /tmp/_LBench/src/spoofer.tar.gz https://www.caida.org/projects/spoofer/downloads/spoofer-1.4.2.tar.gz
            cd /tmp/_LBench/src/
            tar xvf spoofer.tar.gz && cd spoofer-1.4.2
            ./configure && make
            cp prober/spoofer-prober /usr/sbin/spoofer-prober
            cd /tmp && rm -rf /tmp/_LBench/src/spoofer* && rm -rf /tmp/_LBench/bin/spoofer*
        elif [ "${Var_OSRelease}" = "fedora" ]; then
            echo -e "${Msg_Warning}未检测到Spoofer模块，正在安装..."
            dnf install -q -y wget make gcc gcc-c++ traceroute openssl-devel protobuf-devel bison flex libpcap-devel
            mkdir -p /tmp/_LBench/src/
            mkdir -p /tmp/_LBench/bin/
            wget -qO /tmp/_LBench/src/spoofer.tar.gz https://www.caida.org/projects/spoofer/downloads/spoofer-1.4.2.tar.gz
            cd /tmp/_LBench/src/
            tar xvf spoofer.tar.gz && cd spoofer-1.4.2
            ./configure && make
            cp prober/spoofer-prober /usr/sbin/spoofer-prober
            cd /tmp && rm -rf /tmp/_LBench/src/spoofer* && rm -rf /tmp/_LBench/bin/spoofer*
        elif [ "${Var_OSRelease}" = "alpinelinux" ]; then
            echo -e "${Msg_Warning}未检测到Spoofer模块，正在安装..."
            apk update && apk add traceroute gcc g++ make openssl-dev protobuf-dev libpcap-dev
            mkdir -p /tmp/_LBench/src/
            mkdir -p /tmp/_LBench/bin/
            wget -qO /tmp/_LBench/src/spoofer.tar.gz https://www.caida.org/projects/spoofer/downloads/spoofer-1.4.2.tar.gz
            cd /tmp/_LBench/src/
            tar xvf spoofer.tar.gz && cd spoofer-1.4.2
            ./configure && make
            cp prober/spoofer-prober /usr/sbin/spoofer-prober
            cd /tmp && rm -rf /tmp/_LBench/src/spoofer* && rm -rf /tmp/_LBench/bin/spoofer*
        fi
    fi
    # 二次检测
    if [ ! -f "/usr/sbin/spoofer-prober" ]; then
        echo -e "Spoofer模块安装失败! 请尝试重启程序或者手动安装!"
        exit 1
    fi
}

Global_StartupInit
Check_Virtwhat
Check_Speedtest
Check_BestTrace
Check_Spoofer
clear
Function_GetSystemInfo
Function_ShowSystemInfo
Function_Speedtest_Full
Function_DiskTest_Full
Function_BestTrace_Full
Function_SpooferTest