#!/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}' } # 发包并解压缩 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" 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" ;; "core") restart_script="supervisorctl restart all" ;; *) 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} local package=${2} local reboot=${3} local source_tar="/data/update/package/" local destination_dir="/data/jieling/server" if is_valid_ip "$channel"; then unzip_package $channel $package $source_tar $destination_dir if [[ $reboot -eq 1 ]]; then restart_server "core" "$channel" fi else for ip in $(awk '{print $2}' "txt/$channel") do unzip_package $ip $package $source_tar $destination_dir if [[ $reboot -eq 1 ]]; then restart_server "core" "$ip" fi done fi } # 更新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 for ip in $(awk '{print $2}' "txt/$channel") do unzip_package $ip $package $source_tar $destination_dir restart_server "admin" $ip done fi } # 通用游戏服更新函数 game_update_option() { local action=$1 case $action in "update") local action_desc="打更新包" local script="update_game.sh" ;; "hotfix") local action_desc="打热更包" local script="hotfix_game.sh" ;; "official_hotfix") local action_desc="正式服热更" local script="hotfix_game.sh" local send_to="txt" local reboot=0 ;; "official_reboot") local action_desc="正式服停服更新" local script="hotfix_game.sh" local send_to="txt" local reboot=1 ;; "test_hotfix") local action_desc="测试服热更" local script="hotfix_game.sh" local send_to="ip" local reboot=0 ;; "test_reboot") local action_desc="测试服停服更新" local script="hotfix_game.sh" local send_to="ip" local reboot=1 ;; *) echo -e "${red}无效的选项,请重新输入${NC}" show_menu handle_input return ;; esac echo -e "${yellow}$action_desc${NC}" echo "==============================" # 项目属性 if [ $action = "update" ] || [ $action = "hotfix" ]; then show_file project echo -e "${blue}==============================${NC}" read -rp "请输入项目地址: " project if [ -z "$project" ]; then echo -e "${red}项目地址不能为空,请重新输入${NC}" return fi fi # 包属性 show_file package echo -e "${blue}==============================${NC}" read -rp "请输入包名(不需要带文件后缀):" package if [ -z "$package" ]; then echo -e "${red}包名不能为空,请重新输入${NC}" return fi echo -e "开始执行操作 项目:$project, 包名:$package" if [ "$send_to" = "txt" ]; then show_file script/txt read -rp "请输入文件名称(不需要带文件后缀): " channel echo -e "开始发送 包名:$package, channel:$channel" game_send_package "${channel}.txt" "$package" "$reboot" elif [ "$send_to" = "ip" ]; then read -rp "请输入游戏服ip: " ip echo -e "开始发送 包名:$package, ip:$ip" game_send_package "$ip" "$package" "$reboot" else bash "$script" "$project" "$package" fi } # 通用GM更新函数 gm_option() { local action=$1 case $action in "package") local action_desc="打包" local script="update_gm.sh" ;; "single_update") local action_desc="单机器更新" local send_to="ip" ;; "batch_update") local action_desc="批量更新" local send_to="txt" ;; # "single_reboot") # local action_desc="单机器重启" # ;; # "batch_reboot") # local action_desc="批量重启" # ;; *) echo -e "${red}无效的选项,请重新输入${NC}" show_menu handle_input return ;; esac echo -e "${yellow}$action_desc${NC}" if [ "$action" = "package" ]; then show_file project echo -e "${blue}==============================${NC}" read -rp "请输入表所在游戏项目地址: " project bash "$script" "$project" echo -e "gm打包完成" elif [ "$action" = "single_update" ]; then read -rp "请输入游戏服ip: " ip echo -e "开始更新gm" gm_send_package "$ip" elif [ "$action" = "batch_update" ]; then echo -e "开始更新gm" gm_send_package gm_ip.txt elif [ "$action" = "single_reboot" ]; then read -rp "请输入游戏服ip: " ip echo -e "开始重启gm" restart_server "admin" "$ip" elif [ "$action" = "batch_reboot" ]; then local path="/data/update/script/txt/gm_ip.txt" for ip in $(awk '{print $2}' "${path}") do echo -e "开始更新gm $ip" restart_server "admin" "$ip" done fi } # 通用的更新函数 update_server() { 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 } # 游戏服更新子菜单 game_menu(){ echo -e "================================" 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}" } # 游戏服更新 update_game(){ while true; do game_menu read -rp "请输入选项编号: " choice case $choice in 1) game_update_option "update" ;; # 游戏服更新:打更新包 2) game_update_option "hotfix" ;; # 游戏服更新:打热更包 3) game_update_option "official_hotfix" ;; # 游戏服更新:正式服热更 4) game_update_option "official_reboot" ;; # 游戏服更新:正式服停服更新 5) game_update_option "test_hotfix" ;; # 游戏服更新:测试服热更 6) game_update_option "test_reboot" ;; # 游戏服更新:测试服停服更新 0) return ;; *) exit_script ;; esac done } # gm更新子菜单 gm_menu(){ echo -e "================================" echo -e "开始更新${green}gm服${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 "0. ${green}返回主菜单${NC}" echo -e "*. ${red}其他任意键退出程序${NC}" } # gm更新 update_gm(){ while true; do gm_menu read -rp "请输入选项编号: " choice case $choice in 1) gm_option "package" ;; # GM更新:打包 2) gm_option "single_update" ;; # GM更新:单机器更新 3) gm_option "batch_update" ;; # GM更新:批量更新 # 4) gm_option "single_reboot" ;; # GM更新:单机器重启 # 5) gm_option "batch_reboot" ;; # GM更新:批量重启 0) return ;; *) exit_script ;; esac done } # 登陆服更新子菜单 login_menu(){ echo -e "================================" echo -e "开始更新${green}登陆服${NC}" echo -e "1. ${yellow}更新登陆服代码${NC}" echo -e "2. ${yellow}重启登陆服${NC}" echo -e "0. ${green}返回主菜单${NC}" echo -e "*. ${red}其他任意键退出程序${NC}" } # 登陆服更新 login(){ while true; do login_menu read -rp "请输入选项编号: " choice case $choice in 1) update_server "tomcat" "update_login.sh" ;; 2) restart_bol "tomcat" ;; 0) return ;; *) exit_script ;; esac done } # 支付服更新子菜单 pay_menu(){ echo -e "================================" echo -e "开始更新${green}支付服${NC}" echo -e "1. ${yellow}更新支付服代码${NC}" echo -e "2. ${yellow}重启支付服${NC}" echo -e "0. ${green}返回主菜单${NC}" echo -e "*. ${red}其他任意键退出程序${NC}" } # 支付服更新 pay(){ while true; do pay_menu read -rp "请输入选项编号: " choice case $choice in 1) update_server "delivery" "update_delivery.sh" ;; 2) restart_bol "delivery" ;; 0) return ;; *) exit_script ;; esac done } # 敏感词服菜单 mingan_menu(){ echo -e "================================" echo -e "开始更新${green}敏感词服${NC}" echo -e "1. ${yellow}更新敏感词服代码${NC}" echo -e "2. ${yellow}重启敏感词服${NC}" echo -e "0. ${green}返回主菜单${NC}" echo -e "*. ${red}其他任意键退出程序${NC}" } # 敏感词服更新 mingan(){ while true; do mingan_menu read -rp "请输入选项编号: " choice case $choice in 1) update_server "sensitive" "update_sensitive.sh" ;; 2) restart_bol "sensitive" ;; 0) return ;; *) exit_script ;; esac done } # 展示菜单选项 show_menu() { echo -e "================================" echo -e "欢迎使用${blue}戒灵更新脚本${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}" } # 处理用户输入 handle_input() { read -rp "请输入选项编号: " choice case $choice in 1) update_game ;; 2) update_gm ;; 3) login ;; 4) pay ;; 5) mingan ;; 0) exit_script ;; *) echo -e "${red}无效的选项,请重新输入${NC}" ;; esac } # 主程序入口 main() { while true; do show_menu handle_input done } # 脚本开始执行 main