#!/bin/bash # 删除命令乱码解决 stty erase ^h # 文字颜色 red='\033[31m' green='\033[32m' yellow='\033[33m' blue='\033[34m' # shellcheck disable=SC2034 purple='\033[35m' # shellcheck disable=SC2034 cyan='\033[36m' # shellcheck disable=SC2034 white='\033[37m' NC='\033[0m' # 恢复默认颜色 # 判断一个字符串是否是合法的IP地址 is_valid_ip() { local ip=$1 local pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$" if [[ $ip =~ $pattern ]]; then # 检查每个数字是否在0到255之间 local IFS='.' read -ra octets <<< "$ip" for octet in "${octets[@]}"; do if (( octet < 0 || octet > 255 )); then return 1 fi done return 0 else return 1 fi } # 显示指定目录下的文件或目录 show_file(){ filer=$1 find /data/update/"$filer" -maxdepth 1 \( -type f -o -type d \) -printf "%T@\t%-20f\n" | sort -n | awk '{print strftime("%Y-%m-%d %H:%M:%S", $1)"\t"$2}' } # 获取当前时间,精确到秒,格式年月日时分秒 get_current_time() { local current_time current_time=$(date +"%Y%m%d%H%M%S") echo "$current_time" } # 发包并解压缩 unzip_package(){ # 服务器地址 local ip=${1} # tar 包名 local package=${2}.tar.gz # 源服务器上的tar压缩包路径 local source_tar=${3} # 游戏服目标服务器上的目标目录路径 local destination_dir=${4} if [ -e $source_tar ]; then echo "正在处理服务器 $ip" scp "$source_tar/$package" "$ip:$destination_dir" || { echo "SCP 失败"; exit 1; } ssh "$ip" "tar -zxvf $destination_dir/$package -C $destination_dir" ssh "$ip" "rm -f $destination_dir/$package" echo "处理完成服务器 $ip " else echo "$source_tar/$package 不存在,请先去打包!" return fi } # 通用的重启函数 restart_server() { local server_name=$1 local ip=$2 local restart_script="" case $server_name in "tomcat") restart_script="bash /usr/local/apache-tomcat-7.0.79/login_reboot.sh" ;; "delivery") restart_script="bash /data/jieling/delivery-server/pay_reboot.sh" ;; "sensitive") restart_script="bash /data/jieling/sensitiveWordFilter/bin/mingan_reboot.sh" ;; "admin") restart_script="bash /data/jieling/gm/gm_reboot.sh" ;; "super") restart_script="supervisorctl restart all" ;; "coreStop") restart_script="bash /data/jieling/server/bin/stop.sh core1" ;; "coreStart") restart_script="bash /data/jieling/server/bin/start.sh core1" ;; *) echo -e "${red}无效的服务器名称${NC}" exit 1 ;; esac ssh "$ip" "$restart_script" ssh "$ip" "ps -ef | grep $server_name" echo "${server_name} ${ip} 重启完成" } # 游戏代码发送包并重启 game_send_package() { local channel=${1} # ip还是文本更新 local package=${2} # 包名 local reboot=${3} # 是否重启(分辨热更) local source_tar="/data/update/package/" local destination_dir="/data/jieling/server" # 停服更新 if [[ $reboot -eq 1 ]]; then if is_valid_ip "$channel"; then unzip_package $channel $package $source_tar $destination_dir restart_server "coreStop" "$channel" sleep 5 restart_server "coreStart" "$channel" else for ip in $(awk '{print $2}' "txt/$channel") do unzip_package $ip $package $source_tar $destination_dir restart_server "super" "$ip" done fi else # 热更新 if is_valid_ip "$channel"; then unzip_package $channel $package $source_tar $destination_dir else for ip in $(awk '{print $2}' "txt/$channel") do unzip_package $ip $package $source_tar $destination_dir done fi fi } # 通用的更新函数 update_code() { local server_name=$1 local update_script=$2 echo -e "${yellow}${server_name}更新${NC}" read -rp "请输入${server_name}的ip地址: " ip echo -e "开始更新${server_name},ip:$ip" bash "${update_script}" "$ip" read -r -p "更新完毕,是否需要重启(Y/N): " input case $input in [yY][eE][sS]|[yY]) restart_server "$server_name" "$ip" ;; *) echo "over..." exit 0 ;; esac } # 通用的重启判断函数 restart_bol() { local server_name=$1 echo -e "${yellow}${server_name}重启${NC}" read -rp "请输入${server_name}的ip地址: " ip echo -e "开始重启${server_name},ip:$ip" restart_server "$server_name" "$ip" } # 退出脚本 exit_script() { echo -e "${red}谢谢使用,再见!${NC}" exit 0 } # 游戏服更新 update_game(){ while true; do echo -e "开始更新${green}游戏服${NC}" echo -e "1. ${yellow}更新包${NC}" echo -e "2. ${yellow}正式服更新${NC}" echo -e "3. ${yellow}测试服更新${NC}" echo -e "4. ${yellow}热更包${NC}" echo -e "5. ${yellow}正式服热更${NC}" echo -e "6. ${yellow}测试服热更${NC}" echo -e "0. ${green}返回主菜单${NC}" echo -e "*. ${red}其他任意键退出程序${NC}" read -rp "请输入选项编号: " choice case $choice in 1) game_update_option "create_update_package" ;; # 游戏服更新:打更新包 2) game_update_option "official_reboot" ;; # 游戏服更新:正式服停服更新 3) game_update_option "test_reboot" ;; # 游戏服更新:测试服停服更新 4) game_update_option "create_hotfix_package" ;; # 游戏服更新:打热更包 5) game_update_option "official_hotfix" ;; # 游戏服更新:正式服热更 6) game_update_option "test_hotfix" ;; # 游戏服更新:测试服热更 0) return ;; *) exit_script ;; esac done } # 通用游戏服更新函数 game_update_option() { echo -e "${yellow}游戏服更新开始...${NC}" local action=$1 local current_time=get_current_time case $action in "create_update_package") game_code_build "update" "update_game.sh" ;; "official_reboot") game_code_official "update" "1" ;; "test_reboot") game_code_test "update" "1" ;; "create_hotfix_package") game_code_build "hotfix" "hotfix_game.sh" ;; "official_hotfix") game_code_official "hotfix" "0" ;; "test_hotfix") game_code_test "hotfix" "0" ;; *) echo -e "${red}无效的选项,请重新输入${NC}" handle_menu return ;; esac } # 游戏代码打包 game_code_build(){ local type=$1 local script=$2 show_file project | grep master read -rp "请输入项目地址: " project bash "${script}" "${project}" "${project}_${type}_${current_time}" } # 游戏代码正式更新 game_code_official(){ local type=$1 local reboot=$2 show_file package | grep "${type}" read -rp "请输入包名(不需要带文件后缀):" package show_file script/txt read -rp "请输入文件名称(不需要带文件后缀): " channel echo -e "开始发送 包名:$package, 渠道:$channel" game_send_package "${channel}.txt" "$package" "${reboot}" } # 游戏代码测试更新 game_code_test(){ local type=$1 local reboot=$2 show_file package | grep "${type}" read -rp "请输入包名(不需要带文件后缀):" package read -rp "请输入游戏服ip: " ip echo -e "开始发送 包名:$package, ip:$ip" game_send_package "$ip" "$package" "${reboot}" } # gm更新 update_gm(){ while true; do echo -e "开始更新${green}gm服${NC}" echo -e "1. ${yellow}打包${NC}" echo -e "2. ${yellow}单机器更新${NC}" echo -e "3. ${yellow}批量更新${NC}" echo -e "0. ${green}返回主菜单${NC}" echo -e "*. ${red}其他任意键退出程序${NC}" read -rp "请输入选项编号: " choice case $choice in 1) gm_option "package" ;; # GM更新:打包 2) gm_option "single_update" ;; # GM更新:单机器更新 3) gm_option "batch_update" ;; # GM更新:批量更新 0) return ;; *) exit_script ;; esac done } # 通用GM更新函数 gm_option() { local action=$1 case $action in "package") show_file project | grep "master" read -rp "请输入表所在游戏项目地址: " project bash "update_gm.sh" "$project" echo -e "gm打包完成" ;; "single_update") read -rp "请输入游戏服ip: " ip echo -e "开始更新gm" gm_send_package "$ip" ;; "batch_update") echo -e "开始更新gm" gm_send_package gmip.txt ;; *) echo -e "${red}无效的选项,请重新输入${NC}" handle_menu return ;; esac } # 更新gm gm_send_package() { local channel=${1} local package=gm local source_tar="/data/update/project/miduo_gm/gm" local destination_dir="/data/jieling/gm" if is_valid_ip "$channel"; then unzip_package "$channel" $package $source_tar $destination_dir restart_server "admin" "$channel" else # shellcheck disable=SC2013 for ip in $(awk '{print $2}' "txt/$channel") do unzip_package "$ip" $package $source_tar $destination_dir restart_server "admin" "$ip" done fi } # 登陆服更新 update_login(){ while true; do echo -e "开始更新${green}登陆服${NC}" echo -e "1. ${yellow}更新登陆服代码${NC}" echo -e "2. ${yellow}重启登陆服${NC}" echo -e "0. ${green}返回主菜单${NC}" echo -e "*. ${red}其他任意键退出程序${NC}" read -rp "请输入选项编号: " choice case $choice in 1) update_code "tomcat" "update_login.sh" ;; 2) restart_bol "tomcat" ;; 0) return ;; *) exit_script ;; esac done } # 支付服更新 update_pay(){ while true; do echo -e "开始更新${green}支付服${NC}" echo -e "1. ${yellow}更新支付服代码${NC}" echo -e "2. ${yellow}重启支付服${NC}" echo -e "0. ${green}返回主菜单${NC}" echo -e "*. ${red}其他任意键退出程序${NC}" read -rp "请输入选项编号: " choice case $choice in 1) update_code "delivery" "update_delivery.sh" ;; 2) restart_bol "delivery" ;; 0) return ;; *) exit_script ;; esac done } # 敏感词服更新 update_mingan(){ while true; do echo -e "开始更新${green}敏感词服${NC}" echo -e "1. ${yellow}更新敏感词服代码${NC}" echo -e "2. ${yellow}重启敏感词服${NC}" echo -e "0. ${green}返回主菜单${NC}" echo -e "*. ${red}其他任意键退出程序${NC}" read -rp "请输入选项编号: " choice case $choice in 1) update_code "sensitive" "update_sensitive.sh" ;; 2) restart_bol "sensitive" ;; 0) return ;; *) exit_script ;; esac done } # 处理用户输入 handle_menu() { local current_time=get_current_time echo -e "****************************" echo -e "${blue}欢迎使用戒灵更新脚本-${current_time}${NC}" echo -e "1. ${yellow}游戏服更新${NC}" echo -e "2. ${yellow}gm后台更新${NC}" echo -e "3. ${yellow}登陆服更新${NC}" echo -e "4. ${yellow}支付服更新${NC}" echo -e "5. ${yellow}敏感词更新${NC}" echo -e "0. ${red}退出${NC}" echo -e "****************************" read -rp "请输入选项编号: " choice case $choice in 1) update_game ;; 2) update_gm ;; 3) update_login ;; 4) update_pay ;; 5) update_mingan ;; 0) exit_script ;; *) echo -e "${red}无效的选项,请重新输入${NC}" ;; esac } # 主程序入口 main() { while true; do handle_menu done } # 脚本开始执行 main