#!/bin/bash

# -----------------------------------
# Minecraft服务器部署脚本用户须知/协议
# 脚本开发者: bilibili@請叫我零贰
# 脚本版本: v1.0
# 服务器安装版本: 1.21.4 官网原生
# JDK版本: 24:latest
# 制作不易，还请点赞投币收藏
# 投喂方式: 微信号 Kagurazaka02
# -----------------------------------

printf "\n\n\n\n\n欢迎使用零贰的Minecraft原版服务器快速部署脚本。\n在继续使用和安装前，请您给予足够的权限运行该脚本并仔细阅读并同意以下用户协议：\n\n-----------------------------------------------\n【Minecraft服务器部署脚本用户协议】\n1. 脚本仅供个人或团队部署私有Minecraft服务器使用，禁止用于任何商业用途。\n2. 脚本及其相关文件属于原创作品，禁止复制、修改、二次发布、转售等。\n3. 脚本提供免费工具，不对任何技术性问题负责，使用者需自行承担责任。\n4. 使用者应遵守Mojang的《Minecraft最终用户许可协议》(EULA)及相关法律。\n5. 禁止利用本脚本从事违法活动或侵犯他人权益的行为。\n6. 如违反条款，开发者有权采取措施。\n7. 本脚本可能会更新，开发者保留随时修改或终止脚本的权利。\n-----------------------------------------------\n\n继续安装即表示您已阅读并同意上述协议内容。\n\n[1] 同意并继续安装 | [2] 不同意并退出安装\n"; read -p "请输入1或2: " agreechoice; case "$agreechoice" in 1) echo "您已同意协议，继续安装...";; 2) echo "您不同意协议，安装已退出。"; exit 0;; *) echo "无效输入，安装已退出。"; exit 0;; esac
check=0;echo "";echo "是否需要自定义安装目录";echo "[1] 是 | [2] 否";read -p "请输入1或2: " dirchoice;case "$dirchoice" in 1) while [ "$check" != "02" ]; do read -p "请输入自定义安装目录 例[/opt/***]: " installdir;installdir="${installdir%/}";if [ -f "$installdir/eula.txt" ] && [ -f "$installdir/server.properties" ]; then echo "已有服务器相关文件，请检查是否存在相关文件，即将退出安装";exit 0;else mkdir -p "$installdir";fi;if [ -d "$installdir" ]; then echo "你的安装路径是：${installdir}/";echo "";echo "是否在这个目录下安装 [1]是 [2]不是";read -p "请输入1或2: " check;if [ "$check" -eq "1" ]; then check=02;else echo "";fi;else echo "错误：'$installdir' 不是一个有效目录。请重新输入一个有效的目录路径。";fi;done;check=0;;2) installdir=/opt/minecraft;if [ -f "$installdir/eula.txt" ] && [ -f "$installdir/server.properties" ]; then echo "已有服务器相关文件，请检查是否存在相关文件，即将退出安装";exit 0;else mkdir -p "$installdir";fi;;*) echo "ERROR 错误的值";continue;;esac;if ! curl -o "$installdir"/server.jar https://piston-data.mojang.com/v1/objects/4707d00eb834b446575d89a61a11b5d548d8c001/server.jar; then echo "下载 server.jar 失败，即将退出安装";exit 0;fi;jdkdownload=$(curl -s https://jdk.java.net/24/ | grep -Eo '[^"]*linux-x64_bin.tar.gz' | head -n 1);if ! curl -o "$installdir"/jdk24.tar.gz "$jdkdownload"; then echo "下载 jdk24 失败，即将退出安装";exit 0;fi
tar -xvzf "$installdir"/jdk24.tar.gz -C "$installdir"/;rm -rf "$installdir"/jdk24.tar.gz;echo "";total_mem=$(free -g | awk '/^Mem:/{print $2}');check_xmx(){ while [ "$check" != "1" ];do read -p "输入游戏服务器允许使用的最大内存[单位GB 例如1GB则输入1]: " xmx;if [[ -z "$xmx" || ! "$xmx" =~ ^[0-9]+$ ]];then echo "请输入有效的数字。";continue;fi;while [ "$xmx" -gt "$total_mem" ];do echo "输入的内存值超过了本机可用内存。本机最大可用内存为 ${total_mem}GB，请重新输入。";read -p "输入游戏服务器允许使用的最大内存[单位GB 例如1GB则输入1]: " xmx;if [[ -z "$xmx" || ! "$xmx" =~ ^[0-9]+$ ]];then echo "请输入有效的数字。";continue;fi;done;if [[ "$xmx" -gt 0 && "$xmx" -le "$total_mem" ]];then check=1;fi;done;check=0;};check_xms(){ while [ "$check" != "1" ];do read -p "输入游戏服务器的初始启动内存[单位GB 例如1GB则输入1]: " xms;if [[ -z "$xms" || ! "$xms" =~ ^[0-9]+$ ]];then echo "请输入有效的数字。";continue;fi;while [ "$xms" -gt "$xmx" ];do echo "初始启动内存不能大于最大内存，请重新输入。";read -p "输入游戏服务器的初始启动内存[单位GB 例如1GB则输入1]: " xms;if [[ -z "$xms" || ! "$xms" =~ ^[0-9]+$ ]];then echo "请输入有效的数字。";continue;fi;done;if [[ "$xms" -gt 0 && "$xms" -le "$xmx" ]];then check=1;fi;done;check=0;};check_xmx;check_xms;cat << EOF > "$installdir"/start.sh
"$installdir"/jdk-24/bin/java -Xmx${xmx}G -Xms${xms}G -XX:SoftMaxHeapSize=${xmx}G -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -jar "$installdir"/server.jar nogui  
EOF
chmod +x "$installdir"/start.sh; attempts=0; max_attempts=3; cd "$installdir"/; sh "$installdir"/start.sh; sleep 5; while [ ! -f "$installdir/eula.txt" ] && [ $attempts -lt $max_attempts ]; do if [ -f "$installdir/eula.txt" ]; then break; else sh "$installdir"/start.sh; ((attempts++)); sleep 5; fi; done; if [ -f "$installdir/eula.txt" ]; then sed -i 's/eula=false/eula=true/g' "$installdir"/eula.txt; echo "set eula=true"; else echo "安装失败：无法生成 eula.txt 文件"; exit 0; fi; echo "----------基本信息----------"; ipaddr=$(ip addr show | awk '/inet / && !/inet6/ && !/127.0.0.1/ {sub(/\/.*$/, "", $2); print $2; exit}'); if [ -f "$installdir/server.properties" ]; then port=$(grep 'query.port=' "$installdir"/server.properties | cut -d'=' -f2); echo "JAVA版本=jdk24"; echo "游戏版本=1.21.1"; cat "$installdir"/server.properties | grep -E '^gamemode' | sed 's/^gamemode/游戏模式/'; cat "$installdir"/server.properties | grep 'difficulty' | sed 's/^difficulty/游戏难度/'; cat "$installdir"/server.properties | grep 'online-mode' | sed 's/^online-mode/正版验证开启情况/'; cat "$installdir"/server.properties | grep 'query.port' | sed 's/^query.port/端口号/'; echo "初始启动内存=${xms}GB"; echo "最大运行内存=${xmx}GB"; echo "服务器安装目录=${installdir}"; echo "服务器IP地址=${ipaddr}:${port}"; else echo "server.properties 文件尚未生成，无法显示服务器信息。"; fi; echo "-----------------------------"; echo "是否需要修改游戏基本信息"; echo "[1] 修改 | [2] 暂不修改"; read -p "请输入1或2: " setchoice; echo ""
case "$setchoice" in 1) while [ "$check" != "02" ]; do echo "选择要修改的项目"; echo "[1]游戏模式 [2]游戏难度 [3]正版验证 [4]端口号 [5]内存大小 [6]全部修改 [0]退出修改";echo ""; read -p "请输入0-6，一次输入一项: " setting;echo ""; case "$setting" in 0)break;; 1)read -p "请输入新的游戏模式 [0=生存, 1=创造, 2=冒险, 3=旁观者]: " ngm;case "$ngm" in 0)ngm=survival;;1)ngm=creative;;2)ngm=adventure;;3)ngm=spectator;;*)echo "输入错误，请输入有效的游戏模式 (0-3)";continue;;esac;sed -i "s/^gamemode=.*/gamemode=${ngm}/" "$installdir/server.properties";; 2)read -p "请输入新的游戏难度 [0=和平, 1=简单, 2=普通, 3=困难]: " nd;case "$nd" in 0)nd=peaceful;;1)nd=easy;;2)nd=normal;;3)nd=hard;;*)echo"输入错误，请输入有效的游戏难度 (0-3)";continue;;esac;sed -i "s/^difficulty=.*/difficulty=${nd}/" "$installdir/server.properties";; 3)read -p "是否开启正版验证 [0=关闭,1=开启]: " nom;case "$nom" in 0)nom=false;;1)nom=true;;*)echo"输入错误，请输入有效值";continue;;esac;sed -i "s/^online-mode=.*/online-mode=${nom}/" "$installdir/server.properties";; 4)read -p "请输入新的端口号: " np;sed -i "s/^query\.port=.*/query.port=${np}/" "$installdir/server.properties" ;;
5)check_xmx() { while [ "$check" != "02" ]; do read -p "输入游戏服务器允许使用的最大内存[单位GB 例如1GB则输入1]: " xmx;echo "";if [[ -z "$xmx" || ! "$xmx" =~ ^[0-9]+$ ]]; then echo "请输入有效的数字。";echo "";continue;fi; while [ "$xmx" -gt "$total_mem" ]; do echo "输入的内存值超过了本机可用内存。本机最大可用内存为 ${total_mem}GB，请重新输入。";echo "";read -p "输入游戏服务器允许使用的最大内存[单位GB 例如1GB则输入1]: " xmx;if [[ -z "$xmx" || ! "$xmx" =~ ^[0-9]+$ ]]; then echo "请输入有效的数字。";echo "";continue;fi; done; if [[ "$xmx" -gt 0 && "$xmx" -le "$total_mem" ]]; then check=02;fi; done; check=0;};check_xms() { while [ "$check" != "02" ]; do echo"";read -p "输入游戏服务器的初始启动内存[单位GB 例如1GB则输入1]: " xms;echo "";if [[ -z "$xms" || ! "$xms" =~ ^[0-9]+$ ]]; then echo "请输入有效的数字。";echo "";continue;fi; while [ "$xms" -gt "$xmx" ]; do echo "初始启动内存不能大于最大内存，请重新输入。";echo "";read -p "输入游戏服务器的初始启动内存[单位GB 例如1GB则输入1]: " xms;if [[ -z "$xms" || ! "$xms" =~ ^[0-9]+$ ]]; then echo "请输入有效的数字。";echo "";continue;fi; done; if [[ "$xms" -gt 0 && "$xms" -le "$xmx" ]]; then check=02;fi; done; check=0; };check_xmx;check_xms;cat << EOF > "$installdir"/start.sh
"$installdir"/jdk-24/bin/java -Xmx${xmx}G -Xms${xms}G -XX:SoftMaxHeapSize=${xmx}G -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -jar "$installdir"/server.jar nogui
EOF
;;6) read -p "请输入新的游戏模式 [0=生存, 1=创造, 2=冒险, 3=旁观者]: " newgamemode; case "$newgamemode" in 0) newgamemode=survival;; 1) newgamemode=creative;; 2) newgamemode=adventure;; 3) newgamemode=spectator;; *) echo "输入错误，请输入有效的游戏模式 (0-3)"; continue;; esac; sed -i "s/^gamemode=.*/gamemode=${newgamemode}/" "$installdir/server.properties"; echo "游戏模式已经修改为: $newgamemode"; echo ""; read -p "请输入新的游戏难度 [0=和平, 1=简单, 2=普通, 3=困难]: " newdifficulty; case "$newdifficulty" in 0) newdifficulty=peaceful;; 1) newdifficulty=easy;; 2) newdifficulty=normal;; 3) newdifficulty=hard;; *) echo "输入错误，请输入有效的游戏难度 (0-3)"; continue;; esac; sed -i "s/^difficulty=.*/difficulty=${newdifficulty}/" "$installdir/server.properties"; echo "游戏难度已经修改为: $newdifficulty"; echo ""; read -p "是否开启正版验证 [0=关闭,1=开启]: " newonlinemode; case "$newonlinemode" in 0) newonlinemode=false;; 1) newonlinemode=true;; *) echo "输入错误，请输入有效值"; continue;; esac; sed -i "s/^online-mode=.*/online-mode=${newonlinemode}/" "$installdir/server.properties"; echo "正版验证已经修改为: $newonlinemode"; echo ""; read -p "请输入新的端口号: " newport; sed -i "s/^query\.port=.*/query.port=${newport}/" "$installdir/server.properties"; echo "端口号已经修改为: $newport"; echo "";check_xmx() { while [ "$check" != "02" ]; do read -p "输入游戏服务器允许使用的最大内存[单位GB 例如1GB则输入1]: " xmx;echo "";if [[ -z "$xmx" || ! "$xmx" =~ ^[0-9]+$ ]]; then echo "请输入有效的数字。";echo "";continue;fi; while [ "$xmx" -gt "$total_mem" ]; do echo "输入的内存值超过了本机可用内存。本机最大可用内存为 ${total_mem}GB，请重新输入。";echo "";read -p "输入游戏服务器允许使用的最大内存[单位GB 例如1GB则输入1]: " xmx;if [[ -z "$xmx" || ! "$xmx" =~ ^[0-9]+$ ]]; then echo "请输入有效的数字。";echo "";continue;fi; done; if [[ "$xmx" -gt 0 && "$xmx" -le "$total_mem" ]]; then check=02;fi; done; check=0;};check_xms() { while [ "$check" != "02" ]; do echo"";read -p "输入游戏服务器的初始启动内存[单位GB 例如1GB则输入1]: " xms;echo "";if [[ -z "$xms" || ! "$xms" =~ ^[0-9]+$ ]]; then echo "请输入有效的数字。";echo "";continue;fi; while [ "$xms" -gt "$xmx" ]; do echo "初始启动内存不能大于最大内存，请重新输入。";echo "";read -p "输入游戏服务器的初始启动内存[单位GB 例如1GB则输入1]: " xms;if [[ -z "$xms" || ! "$xms" =~ ^[0-9]+$ ]]; then echo "请输入有效的数字。";echo "";continue;fi; done; if [[ "$xms" -gt 0 && "$xms" -le "$xmx" ]]; then check=02;fi; done; check=0; };check_xmx;check_xms;cat << EOF > "$installdir"/start.sh
"$installdir"/jdk-24/bin/java -Xmx${xmx}G -Xms${xms}G -XX:SoftMaxHeapSize=${xmx}G -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -jar "$installdir"/server.jar nogui
EOF
echo "最小运行内存已经修改为: ${xms}GB";echo "最大运行内存已经修改为: ${xmx}GB"; ;;*) ;;esac;echo "----------基本信息----------";ipaddr=$(ip addr show | awk '/inet / && !/inet6/ && !/127.0.0.1/ {sub(/\/.*$/, "", $2); print $2; exit}');if [ -f "$installdir/server.properties" ]; then port=$(grep 'query.port=' "$installdir"/server.properties | cut -d'=' -f2);echo "JAVA版本=jdk24";echo "游戏版本=1.21.1";cat "$installdir"/server.properties | grep -E '^gamemode' | sed 's/^gamemode/游戏模式/';cat "$installdir"/server.properties | grep 'difficulty' | sed 's/^difficulty/游戏难度/';cat "$installdir"/server.properties | grep 'online-mode' | sed 's/^online-mode/正版验证开启情况/';cat "$installdir"/server.properties | grep 'query.port' | sed 's/^query.port/端口号/';echo "初始启动内存=${xms}GB";echo "最大运行内存=${xmx}GB";echo "服务器安装目录=${installdir}";echo "服务器IP地址=${ipaddr}:${port}";else echo "server.properties 文件尚未生成，无法显示服务器信息。";fi;echo "-----------------------------";while true; do echo "";echo "是否继续修改: ";read -p "[1]是 | [2]否: " setagain;echo "";if [[ "$setagain" == "1" || "$setagain" == "2" ]]; then break;else echo "请输入 1 或 2";echo "";fi;done;if [ "$setagain" == "2" ]; then check=02;fi;done;check=0 ;;2) ;;*) ;;esac;echo "-----------------------------";echo "是否现在启动服务器";echo "[1] 启动 | [2] 暂不启动";read -p "请输入1或2: " runchoice;echo "";case "$runchoice" in 1)echo "如果需要修改服务器配置选项请自行修改，配置文件路径为${installdir}/server.properties";echo "后续需要启动服务器时请执行[cd ${installdir}/ && sh ${installdir}/start.sh]即可启动服务器，无需再次执行部署脚本";echo "!!!---10秒后将以默认配置启动服务器---!!!";sleep 10;sh "$installdir"/start.sh ;;*)echo "如果需要修改服务器配置选项请自行修改，配置文件路径为${installdir}/server.properties";echo "后续需要启动服务器时请执行[cd ${installdir}/ && sh ${installdir}/start.sh]即可启动服务器，无需再次执行部署脚本";cd;exit 0 ;;esac
