#!/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") server_name=core restart_script="supervisorctl restart all" ;; "coreStop") server_name=core1 restart_script="bash /data/jieling/server/bin/stop.sh core1" ;; "coreStart") server_name=core1 restart_script="bash /data/jieling/server/bin/start.sh core1" ;; "coreRestart") server_name=core restart_script="bash /data/jieling/server/bin/reboot_all.sh" ;; *) 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 is_valid_ip "$channel"; then unzip_package $channel $package $source_tar $destination_dir case $reboot in [yY][eE][sS]|[yY]) restart_server "coreRestart" "$channel" ;; *) echo "over..." ;; esac else for ip in $(awk '{print $2}' "txt/$channel.txt") do unzip_package $ip $package $source_tar $destination_dir case $reboot in [yY][eE][sS]|[yY]) restart_server "super" "$ip" ;; *) echo "over..." ;; esac done fi } # 通用的更新函数 update_code() { local server_name=$1 local update_script=$2 echo -e "${yellow}${server_name}更新${NC}" read -rp "请输入${server_name}的ip地址: " ip read -r -p "是否需要重启(Y/N): " input echo -e "开始更新${server_name},ip:$ip" bash "${update_script}" "$ip" 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 "${blue}************************************${NC}" echo -e "${purple}开始更新游戏服...${NC}" echo -e "1.打更新包" echo -e "2.打热更包" echo -e "3.更新" echo -e "0.返回主菜单" echo -e "*.${red}其他任意键退出程序${NC}" echo -e "${blue}************************************${NC}" read -rp "请输入选项编号: " choice case $choice in 1) game_code_build "update" "update_game.sh" ;; # 游戏服更新:打更新包 2) game_code_build "hotfix" "hotfix_game.sh" ;; # 游戏服更新:正式服停服更新 3) game_code_official "update" ;; # 游戏服更新:测试服停服更新 0) return ;; *) exit_script ;; esac done } # 游戏代码打包 game_code_build(){ local type=$1 local script=$2 # shellcheck disable=SC2155 local current_time=$(get_current_time) show_file project | grep master read -rp "请输入项目地址: " project local package="${project}_${type}_${current_time}" echo -e "包名: $package" bash "${script}" "${project}" "${package}" } # 游戏代码正式更新 game_code_official(){ local type=$1 show_file package | grep -E "update|hotfix" read -rp "请输入包名(不需要带文件后缀):" package show_file script/txt read -rp "请输入ip地址或文件名称(不需要带文件后缀): " channel read -rp "是否需要重启(Y/N):" reboot echo -e "开始发送 包名:$package, 渠道:$channel" game_send_package "$channel" "$package" "$reboot" } # 更新gm gm_send_package() { local channel=${1} local package=${2} local source_tar="/data/update/package" 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.txt") do unzip_package "$ip" $package $source_tar $destination_dir restart_server "admin" "$ip" done fi } # 通用GM更新函数 gm_option() { local action=$1 # shellcheck disable=SC2155 local current_time=$(get_current_time) case $action in "package") show_file project | grep "master" read -rp "请输入表所在游戏项目地址: " project local package="gm_${project}_${current_time}" bash "update_gm.sh" "$project" "$package" echo -e "gm打包完成 $package" ;; "update") show_file script/txt read -rp "请输入ip地址或文件名称(不需要带文件后缀): " channel show_file package | grep "gm" read -rp "请输入包名(不需要带文件后缀):" package echo -e "开始更新gm $channel $package" gm_send_package "$channel" "$package" ;; *) echo -e "${red}无效的选项,请重新输入${NC}" handle_menu return ;; esac } # gm更新 update_gm(){ while true; do echo -e "${blue}************************************${NC}" echo -e "${purple}开始更新GM后台...${NC}" echo -e "1.打包" echo -e "2.更新" echo -e "0.返回主菜单" echo -e "*.${red}其他任意键退出程序${NC}" echo -e "${blue}************************************${NC}" read -rp "请输入选项编号: " choice case $choice in 1) gm_option "package" ;; # GM更新:打包 2) gm_option "update" ;; # GM更新:更新 0) return ;; *) exit_script ;; esac done } # 登陆服更新 update_login(){ while true; do echo -e "${blue}************************************${NC}" echo -e "${purple}开始更新登陆服...${NC}" echo -e "1.更新登陆服代码" echo -e "2.重启登陆服" echo -e "0.返回主菜单" echo -e "*.${red}其他任意键退出程序${NC}" echo -e "${blue}************************************${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 "${blue}************************************${NC}" echo -e "${purple}开始更新支付服...${NC}" echo -e "1.更新支付服代码" echo -e "2.重启支付服" echo -e "0.返回主菜单" echo -e "*.${red}其他任意键退出程序${NC}" echo -e "${blue}************************************${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 "${blue}************************************${NC}" echo -e "${purple}开始更新敏感词服...${NC}" echo -e "1.更新敏感词服代码" echo -e "2.重启敏感词服" echo -e "0.返回主菜单" echo -e "*.${red}其他任意键退出程序${NC}" echo -e "${blue}************************************${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 current_time=$(get_current_time) echo -e "${blue}************************************${NC}" echo -e "${purple}欢迎使用戒灵更新脚本...${current_time}${NC}" echo -e "1.游戏服更新" echo -e "2.gm后台更新" echo -e "3.登陆服更新" echo -e "4.支付服更新" echo -e "5.敏感词更新" echo -e "0.${red}退出${NC}" echo -e "${blue}************************************${NC}" 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