OpenSUSEでMinecraft Server(BE版)を建てる

Setting Up a Minecraft Bedrock Edition Server on OpenSUSE

はじめに

以前わたしがOracleCloudでマイクラサーバーを作成していたのですが、その時に自動で最新バージョンにアップデート・バックアップを取ってくれる便利なスクリプトがあったことを思い出し探してみました。
ネットの海を探して探してやっと見つけました。
https://jamesachambers.com/minecraft-bedrock-edition-ubuntu-dedicated-server-guide/
これでいざ実装しようかと思った時に、私のサーバーがUbuntuではなく、OpenSUSEで作成していることに気づきましたが、少し修正すれば動くんじゃないかなと思い行ってみました。

1.パッケージマネージャーの変更

パッケージマネージャーをUbuntuのaptからOpenSUSE用のzypperに変更しました。
それに伴ってパッケージ名をnet-toolsnet-tools-deprecated、libcurl4libopenssl1_1 に変更しています。

sudo zypper refresh
sudo zypper update -y
sudo zypper install -y curl unzip screen net-tools-deprecated gawk openssl pigz libcurl4 libopenssl1_1

2.Arm対応部分・不要部分の削除

ARM アーキテクチャ向けの設定を簡略化し、box64 のインストールに関する部分を削除しています。
他にも要らないと思われる部分を削除しました。

3.依存関係チェックの簡略化

Ubuntu 向けの詳細な依存関係チェックを削除し、OpenSUSE 向けにシンプル化しました(ほぼ消しただけ)。

4.サーバーダウンロード部分の変更

downloads/version.htmlをみたときに、そこの部分が上手く機能していなかったみたいなので修正しました。

DownloadURL=$(grep -o 'https://www.minecraft.net/bedrockdedicatedserver/bin-linux/[^"]*' downloads/version.html)

start.shも同じようにURL部分をhttps://www.minecraft.net/bedrockdedicatedserver/bin-linuxから参照するように変更する必要があります。

それに伴ってupdate.shも以下のようにクローンした部分から編集したものを使用するようにしました。

<a href="https://raw.githubusercontent.com/bokumin/MinecraftBedrockServer/master/update.sh">https://raw.githubusercontent.com/bokumin/MinecraftBedrockServer/master/update.sh</a>

おわりに

実際に修正済みのコードはこちらです。
https://github.com/bokumin/MinecraftBedrockServer/blob/master/SetupMinecraft.sh

この方のおかげでマインクラフトに関しての管理が大変楽になったので、感謝しています。
同じように悩んでいらっしゃる方がいれば、参考になれば幸いです。

#!/bin/bash
# Minecraft Server Installation Script - James A. Chambers - https://jamesachambers.com
# Modified for OpenSUSE compatibility

echo "Minecraft Bedrock Server installation script by James A. Chambers"
echo "Modified for OpenSUSE compatibility"
echo "Latest version always at https://github.com/TheRemote/MinecraftBedrockServer"
echo "Don't forget to set up port forwarding on your router!  The default port is 19132"

# Randomizer for user agent
RandNum=$(echo $((1 + $RANDOM % 5000)))

# You can override this for a custom installation directory
DirName=$(readlink -e ~)
if [ -z "$DirName" ]; then
  DirName=~
fi

# Function to read input from user with a prompt
function read_with_prompt {
  variable_name="$1"
  prompt="$2"
  default="${3-}"
  unset $variable_name
  while [[ ! -n ${!variable_name} ]]; do
    read -p "$prompt: " $variable_name </dev/tty
    if [ ! -n "$(which xargs)" ]; then
      declare -g $variable_name=$(echo "${!variable_name}" | xargs)
    fi
    declare -g $variable_name=$(echo "${!variable_name}" | head -n1 | awk '{print $1;}' | tr -cd '[a-zA-Z0-9]._-')
    if [[ -z ${!variable_name} ]] && [[ -n "$default" ]]; then
      declare -g $variable_name=$default
    fi
    echo -n "$prompt : ${!variable_name} -- accept (y/n)?"
    read answer </dev/tty
    if [[ "$answer" == "${answer#[Yy]}" ]]; then
      unset $variable_name
    else
      echo "$prompt: ${!variable_name}"
    fi
  done
}

Update_Scripts() {
  # Remove existing scripts
  rm -f start.sh stop.sh restart.sh fixpermissions.sh revert.sh

  # Download start.sh from repository
  echo "Grabbing start.sh from repository..."
  curl -H "Accept-Encoding: identity" -L -o start.sh https://raw.githubusercontent.com/TheRemote/MinecraftBedrockServer/master/start.sh
  chmod +x start.sh
  sed -i "s:dirname:$DirName:g" start.sh
  sed -i "s:servername:$ServerName:g" start.sh
  sed -i "s:userxname:$UserName:g" start.sh
  sed -i "s<pathvariable<$PATH<g" start.sh

  # Download stop.sh from repository
  echo "Grabbing stop.sh from repository..."
  curl -H "Accept-Encoding: identity" -L -o stop.sh https://raw.githubusercontent.com/TheRemote/MinecraftBedrockServer/master/stop.sh
  chmod +x stop.sh
  sed -i "s:dirname:$DirName:g" stop.sh
  sed -i "s:servername:$ServerName:g" stop.sh
  sed -i "s:userxname:$UserName:g" stop.sh
  sed -i "s<pathvariable<$PATH<g" stop.sh

  # Download restart.sh from repository
  echo "Grabbing restart.sh from repository..."
  curl -H "Accept-Encoding: identity" -L -o restart.sh https://raw.githubusercontent.com/TheRemote/MinecraftBedrockServer/master/restart.sh
  chmod +x restart.sh
  sed -i "s:dirname:$DirName:g" restart.sh
  sed -i "s:servername:$ServerName:g" restart.sh
  sed -i "s:userxname:$UserName:g" restart.sh
  sed -i "s<pathvariable<$PATH<g" restart.sh

  # Download fixpermissions.sh from repository
  echo "Grabbing fixpermissions.sh from repository..."
  curl -H "Accept-Encoding: identity" -L -o fixpermissions.sh https://raw.githubusercontent.com/TheRemote/MinecraftBedrockServer/master/fixpermissions.sh
  chmod +x fixpermissions.sh
  sed -i "s:dirname:$DirName:g" fixpermissions.sh
  sed -i "s:servername:$ServerName:g" fixpermissions.sh
  sed -i "s:userxname:$UserName:g" fixpermissions.sh
  sed -i "s<pathvariable<$PATH<g" fixpermissions.sh

  # Download revert.sh from repository
  echo "Grabbing revert.sh from repository..."
  curl -H "Accept-Encoding: identity" -L -o revert.sh https://raw.githubusercontent.com/TheRemote/MinecraftBedrockServer/master/revert.sh
  chmod +x revert.sh
  sed -i "s:dirname:$DirName:g" revert.sh
  sed -i "s:servername:$ServerName:g" revert.sh
  sed -i "s:userxname:$UserName:g" revert.sh
  sed -i "s<pathvariable<$PATH<g" revert.sh

  # Download clean.sh from repository
  echo "Grabbing clean.sh from repository..."
  curl -H "Accept-Encoding: identity" -L -o clean.sh https://raw.githubusercontent.com/TheRemote/MinecraftBedrockServer/master/clean.sh
  chmod +x clean.sh
  sed -i "s:dirname:$DirName:g" clean.sh
  sed -i "s:servername:$ServerName:g" clean.sh
  sed -i "s:userxname:$UserName:g" clean.sh
  sed -i "s<pathvariable<$PATH<g" clean.sh

  # Download update.sh from repository
  echo "Grabbing update.sh from repository..."
  curl -H "Accept-Encoding: identity" -L -o update.sh https://raw.githubusercontent.com/bokumin/MinecraftBedrockServer/master/update.sh
  chmod +x update.sh
  sed -i "s<pathvariable<$PATH<g" update.sh
}

Update_Service() {
  # Update minecraft server service
  echo "Configuring Minecraft $ServerName service..."
  sudo curl -H "Accept-Encoding: identity" -L -o /etc/systemd/system/$ServerName.service https://raw.githubusercontent.com/TheRemote/MinecraftBedrockServer/master/minecraftbe.service
  sudo chmod +x /etc/systemd/system/$ServerName.service
  sudo sed -i "s:userxname:$UserName:g" /etc/systemd/system/$ServerName.service
  sudo sed -i "s:dirname:$DirName:g" /etc/systemd/system/$ServerName.service
  sudo sed -i "s:servername:$ServerName:g" /etc/systemd/system/$ServerName.service
  if [ -e server.properties ]; then
    sed -i "/server-port=/c\server-port=$PortIPV4" server.properties
    sed -i "/server-portv6=/c\server-portv6=$PortIPV6" server.properties
  fi

  sudo systemctl daemon-reload

  echo -n "Start Minecraft server at startup automatically (y/n)?"
  read answer </dev/tty
  if [[ "$answer" != "${answer#[Yy]}" ]]; then
    sudo systemctl enable $ServerName.service
    # Automatic reboot at 4am configuration
    TimeZone=$(cat /etc/timezone)
    CurrentTime=$(date)
    echo "Your time zone is currently set to $TimeZone.  Current system time: $CurrentTime"
    echo "You can adjust/remove the selected reboot time later by typing crontab -e or running SetupMinecraft.sh again."
    echo -n "Automatically restart and backup server at 4am daily (y/n)?"
    read answer </dev/tty
    if [[ "$answer" != "${answer#[Yy]}" ]]; then
      croncmd="$DirName/minecraftbe/$ServerName/restart.sh 2>&1"
      cronjob="0 4 * * * $croncmd"
      (
        crontab -l | grep -v -F "$croncmd"
        echo "$cronjob"
      ) | crontab -
      echo "Daily restart scheduled.  To change time or remove automatic restart type crontab -e"
    fi
  fi
}

Fix_Permissions() {
  echo "Setting server file permissions..."
  sudo ./fixpermissions.sh -a >/dev/null
}

Check_Dependencies() {
  # Install dependencies required to run Minecraft server in the background
  echo "Checking and installing dependencies..."
  sudo zypper refresh
  sudo zypper update -y

  # Install required packages
  sudo zypper install -y curl unzip screen net-tools-deprecated gawk openssl pigz libcurl4 libopenssl1_1

  # Check for ARM architecture
  if [[ $(uname -m) == *"aarch"* || $(uname -m) == *"arm"* ]]; then
    echo "ARM architecture detected. Installing additional dependencies..."
    sudo zypper install -y qemu-linux-user qemu-tools binfmt-support
  fi

  # Double check curl installation
  if ! command -v curl &>/dev/null; then
    sudo zypper install -y curl
  fi
}

Update_Server() {
   CURRENT_DIR=$(pwd)

   # Create the downloads directory if it doesn't exist
   mkdir -p "$CURRENT_DIR/downloads"
   
  # Retrieve latest version of Minecraft Bedrock dedicated server
  echo "Checking for the latest version of Minecraft Bedrock server..."
  curl -H "Accept-Encoding: identity" -H "Accept-Language: en" -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.33 (KHTML, like Gecko) Chrome/90.0.$RandNum.212 Safari/537.33" -o downloads/version.html https://minecraft.net/en-us/download/server/bedrock/
  #  DownloadURL=$(grep -o 'https://minecraft.azureedge.net/bin-linux/[^"]*' downloads/version.html)
  DownloadURL=$(grep -o 'https://www.minecraft.net/bedrockdedicatedserver/bin-linux/[^"]*' downloads/version.html)
  DownloadFile=$(echo "$DownloadURL" | sed 's#.*/##')
  echo "$DownloadURL"
  echo "$DownloadFile"

  # Download latest version of Minecraft Bedrock dedicated server
  echo "Downloading the latest version of Minecraft Bedrock server..."
  UserName=$(whoami)
  curl -H "Accept-Encoding: identity" -H "Accept-Language: en" -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.33 (KHTML, like Gecko) Chrome/90.0.$RandNum.212 Safari/537.33" -o "downloads/$DownloadFile" "$DownloadURL"
  unzip -o "downloads/$DownloadFile"
}

Check_Architecture() {
  # Check CPU architecture to see if we need to do anything special for the platform the server is running on
  echo "Getting system CPU architecture..."
  CPUArch=$(uname -m)
  echo "System Architecture: $CPUArch"

  # Check for ARM architecture
  if [[ "$CPUArch" == *"aarch"* || "$CPUArch" == *"arm"* ]]; then
    echo "ARM architecture detected. Additional setup may be required."
    # Add ARM-specific setup steps here if needed
  fi

  # Check for x86 (32 bit) architecture
  if [[ "$CPUArch" == *"i386"* || "$CPUArch" == *"i686"* ]]; then
    echo "You are running a 32 bit operating system (i386 or i686) and the Bedrock Dedicated Server has only been released for 64 bit (x86_64). If you have a 64 bit processor, please install a 64 bit operating system to run the Bedrock dedicated server!"
    exit 1
  fi
}

Update_Sudoers() {
  if [ -d /etc/sudoers.d ]; then
    sudoline="$UserName ALL=(ALL) NOPASSWD: /bin/bash $DirName/minecraftbe/$ServerName/fixpermissions.sh -a, /bin/systemctl start $ServerName, /bin/bash $DirName/minecraftbe/$ServerName/start.sh"
    if [ -e /etc/sudoers.d/minecraftbe ]; then
      AddLine=$(sudo grep -qxF "$sudoline" /etc/sudoers.d/minecraftbe || echo "$sudoline" | sudo tee -a /etc/sudoers.d/minecraftbe)
    else
      AddLine=$(echo "$sudoline" | sudo tee /etc/sudoers.d/minecraftbe)
    fi
  else
    echo "/etc/sudoers.d was not found on your system. Please add this line to sudoers using sudo visudo: $sudoline"
  fi
}

# Main script execution starts here

# Check to make sure we aren't running as root
if [[ $(id -u) = 0 ]]; then
  echo "This script is not meant to be run as root. Please run ./SetupMinecraft.sh as a non-root user, without sudo; the script will call sudo when it is needed. Exiting..."
  exit 1
fi

Check_Dependencies

# Check to see if Minecraft server main directory already exists
cd $DirName
if [ ! -d "minecraftbe" ]; then
  mkdir minecraftbe
  cd minecraftbe
else
  cd minecraftbe
  if [ -f "bedrock_server" ]; then
    echo "Migrating old Bedrock server to minecraftbe/old"
    cd $DirName
    mv minecraftbe old
    mkdir minecraftbe
    mv old minecraftbe/old
    cd minecraftbe
    echo "Migration complete to minecraftbe/old"
  fi
fi

# Server name configuration
echo "Enter a short one word label for a new or existing server (don't use minecraftbe)..."
echo "It will be used in the folder name and service name..."

read_with_prompt ServerName "Server Label"

# Remove non-alphanumeric characters from ServerName
ServerName=$(echo "$ServerName" | tr -cd '[a-zA-Z0-9]._-')

if [[ "$ServerName" == *"minecraftbe"* ]]; then
  echo "Server label of minecraftbe is not allowed. Please choose a different server label!"
  exit 1
fi

echo "Enter server IPV4 port (default 19132): "
read_with_prompt PortIPV4 "Server IPV4 Port" 19132

echo "Enter server IPV6 port (default 19133): "
read_with_prompt PortIPV6 "Server IPV6 Port" 19133

if [ -d "$ServerName" ]; then
  echo "Directory minecraftbe/$ServerName already exists!  Updating scripts and configuring service ..."

  # Get username
  UserName=$(whoami)
  cd $DirName
  cd minecraftbe
  cd $ServerName
  echo "Server directory is: $DirName/minecraftbe/$ServerName"

  # Update Minecraft server scripts
  Update_Scripts

  # Service configuration
  Update_Service

  # Sudoers configuration
  Update_Sudoers

  # Fix server files/folders permissions
  Fix_Permissions

  # Setup completed
  echo "Setup is complete.  Starting Minecraft $ServerName server.  To view the console use the command screen -r or check the logs folder if the server fails to start"
  sudo systemctl daemon-reload
  sudo systemctl start "$ServerName.service"

  exit 0
fi

# Create server directory
echo "Creating minecraft server directory ($DirName/minecraftbe/$ServerName)..."
cd $DirName
cd minecraftbe
mkdir $ServerName
cd $ServerName
mkdir downloads
mkdir backups
mkdir logs

Check_Architecture

# Update Minecraft server binary
Update_Server

# Update Minecraft server scripts
Update_Scripts

# Update Minecraft server services
Update_Service

# Sudoers configuration
Update_Sudoers

# Fix server files/folders permissions
Fix_Permissions

# Finished!
echo "Setup is complete.  Starting Minecraft server. To view the console use the command screen -r or check the logs folder if the server fails to start."
sudo systemctl daemon-reload
sudo systemctl start "$ServerName.service"

# Wait up to 30 seconds for server to start
StartChecks=0
while [[ $StartChecks -lt 30 ]]; do
  if screen -list | grep -q "\.$ServerName\s"; then
    break
  fi
  sleep 1
  StartChecks=$((StartChecks + 1))
done

# Force quit if server is still open
if ! screen -list | grep -q "\.$ServerName\s"; then
  echo "Minecraft server failed to start after 30 seconds."
else
  echo "Minecraft server has started.  Type screen -r $ServerName to view the running server!"
fi


Categories: