ほのぼの技術部

技術系記事

Palworldのセーブデータをバックアップする(Azure)

概要

Azureのクラウドストレージを使って、パルサーバーのセーブデータをバックアップする。

  • 見積り
  • ストレージアカウントの作成
  • コンテナーの作成
  • 仮想マシンからストレージアカウントへの紐づけ
  • AzureCLIの導入
  • バックアップとアップロード
  • 動作確認
  • 定期実行化

見積り

  • Azure Blob Storage の価格

https://azure.microsoft.com/ja-jp/pricing/details/storage/blobs/

Standardなコールドで1GB使って約0.5円。

現状のパルセーブデータが6~10MBなので、1万回バックアップしても数円レベル。

ストレージアカウントの作成

Azureのストレージアカウント画面へ遷移

作成

■基本

  • プロジェクトの詳細

  • インスタンスの詳細

    • ストレージアカウント名:任意
    • 地域:任意
    • パフォーマンス:Standard
    • 冗長性:LRS

■詳細設定

  • BLOBストレージ
    • アクセス層:クール

他そのまま

■ネットワーク

ネットワークアクセス:任意

■データ保護

今回は全てチェックを外す

■暗号化

  • 暗号化の種類:MMK
  • BLOBとファイルのみ

確認して作成

コンテナーの作成

作成したストレージアカウントを選択

「コンテナー」メニューより、新しいコンテナーを作成する。

仮想マシンからストレージアカウントへの紐づけ

仮想マシンからストレージアカウントへアクセスできるように、アクセス許可設定を行う。

ストレージアカウントの「アクセス制御(IAM)」メニューより、

「ロールの割り当ての追加」

  • ロール
    • 特権管理者ロール→「ストレージBLOBデータ共同作成者」 を選択
  • メンバー
    • アクセスの割当先:マネージドID
    • メンバー:<接続元の仮想マシンを選択>

「レビューと割り当て」

AzureCLIの導入

仮想マシンからアップロードコマンドを実行するために導入しておく。

https://learn.microsoft.com/ja-jp/cli/azure/install-azure-cli-linux?pivots=apt

curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

バックアップとアップロード

バックアップはパルサーバーのセーブゲームのディレクトリを丸ごとtarボールで固めます。

スクリプトを作成します。

  • pal-backup-and-upload.sh
#!/bin/sh

WORK_PATH="/home/steam/work"
TARBALLNAME="`date +%Y%m%d`.PalSaveData.tar.gz"

az login -i

cd $WORK_PATH
## backup
tar -cvzf ${WORK_PATH}/${TARBALLNAME} -C /home/steam/.steam/SteamApps/common/PalServer/Pal/Saved/ SaveGames

## upload
az storage blob upload -f ${WORK_PATH}/${TARBALLNAME} -c <コンテナーの名前> --account-name <ストレージアカウントの名前> --auth-mode login

az logout

rm ${WORK_PATH}/${TARBALLNAME}

実行権限付与

chmod u+x pal-backup-and-upload.sh

動作確認

./pal-backup-and-upload.sh

Azureのコンテナーにアップロードされていれば成功。

定期実行化

定期実行の設定を行い、毎日バックアップ処理を行うようにする。

EDITOR=vi crontab -e
#3:30にバックアップ実行
30 3 * * * /home/steam/scripts/pal-backup-and-upload.sh

おわりに

ちょうどバックアップをしておいたおかげで、鯖内のプレイヤーデータが消えた時に正常だったデータまでロールバックすることができた。やったね。

Palworldサーバーにシステムメッセージを送る機能を追加する

概要

Palworldサーバーにシステムメッセージを送る機能を構築する。

  • RCONのシステムを構築する。
  • cronを使用した定期実行化。

背景

現状、サーバーは夜稼働しているが、稼働終了時刻になるとなんの前触れもなくサーバーが落ちる。

時間を忘れて熱中していたら、いきなり落ちてびっくりするので、時報のシステムがあれば、プレイヤーに優しい。

目的

サーバーが落ちる数分前に、システムメッセージの時報を定期的に送りたい。

環境

Ubuntu Server 20.04 LTS x64

調査

RCON(Remote Console)というプロトコルを使用すれば実現できるらしい。

https://developer.valvesoftware.com/wiki/Source_RCON_Protocol

ライブラリは様々な言語で提供されていた。

準備

Palworldのワールド設定ファイルの必要項目を設定しておく。

  • RCONEnabled:True
  • RCONPort:25575(初期値)
  • AdminPassword:<password>

RCONクライアントの導入

今回はC言語で提供されているライブラリを使用する。

https://github.com/n0la/rcon

$ apt-get install build-essential cmake check libbsd-dev libglib2.0-dev

$ mkdir build
$ cd build
$ cmake .. -DCMAKE_INSTALL_PREFIX=/usr
$ make
$ sudo make install

コマンドテスト

Palworldのコマンドを実際に実行して疎通確認をする。

https://tech.palworldgame.com/server-commands

コマンドは、チャット時のコマンドのように、頭に「/」は付けない。

ここのパスワードはワールド設定のAdminPasswordを指す。

  • 構文
$ rcon -H <hostip> -p <port> -P <password> <コマンド>
  • テスト
$ rcon -H localhost -p 25575 -P <password> Broadcast "go_to_bed"

メッセージテキストは、空白の手前までしか送信できなかったので、仕方なく「_」で繋ぐことにした。後、日本語を書くと文字化けする。

また、このコマンドだけだと動作はするが、謎のエラーが発生した。

(process:1283): GLib-CRITICAL **: 17:03:16.615: 
g_byte_array_remove_range: assertion 'index_ + length <= array->len' failed

これを解決するためには、timeoutコマンドで、コマンドに制限時間を短時間付けると解消できる。

$ timeout 2 rcon -H localhost -p 25575 -P <password> Broadcast "go_to_bed"

cronで定期実行化

RCON実行スクリプトの作成

RCONのコマンドを実行するスクリプトを作成する。

$ sudo -u steam -s
$ cd /home/steam/scripts
$ vi pal-server-command.sh
#!/bin/sh

MESSAGE="go_to_bed"
timeout 2 rcon -H localhost -p 25575 -P <password> Broadcast $MESSAGE
$ chmod u+x pal-server-command.sh

cronの設定

https://qiita.com/hikouki/items/e744b3a4d356d2af12cf

先ほどの実行スクリプトを2:20に実行するように設定してみる。

$ EDITOR=vi crontab -e
20 2 * * * /home/steam/scripts/pal-server-command.sh

cronサービスの再起動

$ sudo systemctl restart cron

動作確認

ゲーム内で指定した時間に、設定したシステムメッセージが来ればOK。

おわりに

定期的なシステムメッセージを送信する機能を実装した。

できれば日本語対応とかしたい。

Palworldのアップデ―ト対応

概要

ゲームのバージョンが上がり、接続できなくなっていたので、サーバーのバージョンも上げる。

バージョンアップ対応

専用サーバーをダウンロードしたときのコマンドをもう一度叩く

$ sudo -u steam -s

$ steamcmd +login anonymous +app_update 2394010 validate +quit

もし、パスが通っていない、といったエラーで実行できない場合は、その対象のパスを登録して再度実行。

(筆者の場合は/usr/gamesだった。)

$ export PATH=$PATH:/usr/games

おまけ

起動スクリプトの実行前に、このアップデートコマンドを1行挿入しておくと、毎回最新状態で起動してくれるはず。 *2024/02/02追記 その時はsteamcmdコマンドはフルパス(/usr/games/steamcmd)で書くべし

以上。

Palworldのサーバーワールド設定

  • ワールド設定公式マニュアル

https://tech.palworldgame.com/optimize-game-balance

サーバー設定デフォルトファイルからコピー

$ cd ~/.steam/SteamApps/common/PalServer/Pal/Saved/Config/LinuxServer
$ cp ~/.steam/SteamApps/common/PalServer/DefaultPalWorldSettings.ini ./PalWorldSettings.ini

マニュアルに沿って任意の項目を編集

とりあえず下記をやっておけばよさそう。

  • ServerPlayerMaxNum
  • ServerName
  • ServerDescription
  • ServerPassword

下記はお好みで、鯖缶は権限的に持っていた方が安心かも?

  • AdminPassword

因みに、サーバー説明は日本語入力しても問題なく表示された。(サーバー名の方は試してないから分からない。)

AzureでPalworldのプライベートサーバーを構築した(自動起動編)

前回

akinaudeku.hatenablog.com

概要

前回の続きの環境で、下記を行う。

これで、Palworldサーバーを、完全放置で好きな時間に動作させるようにします。

仮想マシンのPalworldサーバーの自動起動

systemdを使って、自動起動を行う。下記を用意する。

Palworldサーバーの実行スクリプトを作成

steamユーザーで実行スクリプトを作成します。

$ sudo -u steam -s
$ cd ~/
$ mkdir scripts
$ vi boot-pal.sh
#!/bin/sh
/home/steam/.steam/SteamApps/common/PalServer/PalServer.sh

実行権限を付けます。

$ chmod u+x boot-pal.sh
$ ls -l boot-pal.sh
-rwxr--r-- 1 steam steam 69 Jan 22 14:14 boot-pal.sh

今回は下記パスにファイルを作成した。

/home/steam/scripts/boot-pal.sh

serviceファイルの作成

マシン起動時にPalworldサーバーの実行スクリプトを実行させるシンプルなサービスを作成する。

内容はシンプルで、先ほどの実行スクリプトを「steam」ユーザーで実行してね、ということを書いた。

理解していない設定項目もあるので、とりあえず記載だけしている箇所もある。

$ cd /etc/systemd/system
$ vi boot-pal.service
[Unit]
Description=Auto Start Up Service for Pal
After=local-fs.target

[Service]
User=steam
Type=simple
ExecStart=/home/steam/scripts/boot-pal.sh

[Install]
WantedBy=multi-user.target

単体テスト

$ sudo systemctl start boot-pal
$ systemctl status boot-pal

Active: active (running)

の文言があって、普通にPalworldサーバー実行したときと同じようなログが表示されていればOK。

ゲームでも確認しておくと尚よい。

サービス自動起動有効設定

$ sudo systemctl enable boot-pal

起動確認

仮想マシンを再起動して、自動起動で動作しているか確認する。

$ systemctl status boot-pal
(省略)
$ ps aux | grep pal
steam        640  0.0  0.0   2616   536 ?        Ss   12:50   0:00 /bin/sh /home/steam/scripts/boot-pal.sh

ゲームで接続できるか確認する。

これで完了。

Azureで仮想マシン自動起動

仮想マシン自動起動には、Azure Automationを使用していきます。

  • Automationアカウントの作成
  • Runbookの作成
  • スケジュールの設定
  • 各種紐づけ

Automationアカウントの作成

Automationアカウント画面から、作成

  • リソースグループ(今回作成したリソースグループを指定)
  • 他任意で
  • マネージドID
    • システム割り当て(今回はこっちで)
  • ネットワーク接続
    • 一旦パブリックで

Runbookの作成

作成したAutomationアカウントのメニューからRunbook→ギャラリーを参照

「Start Azure V2 VMs」を選択

「選択」

Runbook名を入力して「インポート」

編集画面が表示されたら、「テストウィンドウ」へ遷移

以下のパラメーターに必要情報を入力して、「開始」

他の画面と違ってドロップダウンから選べないので打ち間違い注意。

上記3つはスケジュール設定の紐づけで再度入力するので、メモしておくとよい。

テストをすると完了と表示されるが、紐づけのエラーが起きるので、その設定を行う。

Automationと仮想マシンの紐づけ

仮想マシンのサイドメニューの「ID」

システム割り当て済みタブの状態をオンにする。

仮想マシンのサイドメニューの「アクセス制御(IAM)」

このリソースへのアクセス権の付与の項目から「ロール割り当ての追加」

「メンバー」

  • アクセスの割り当て先:マネージドID

マネージドIDの選択

サブスクリプション:従量課金

マネージドID:Automationアカウント

選択:<作成したAutomationアカウントを選択>

「選択」

「レビューと割り当て」

Runbookのテスト

先ほどのRunbookのテストを開始し、完了が表示され、エラーがなくなっていれば成功。

完了すると、対象の仮想マシンが起動しているはず。

スケジュールの設定

仮想マシン自動起動させたい時間に設定します。

Automationアカウントのサイドメニュー→「スケジュール」

スケジュールの追加

お好みで設定。

今回は夜だけ稼働させたいので、毎日夜起動するように設定した。

Runbookとスケジュールの紐づけ

Runbookを発行します。

Automation アカウントのサイドメニュー→「Runbook」

先ほど作成したRunbookの管理画面まで遷移。

Runbookのサイドメニュー→「概要」

「編集」→「ポータルで編集」

先ほど作成したRunbookの編集画面へ遷移し、「公開」

「スケジュールへのリンク」が押せるようになるので、押下

  • スケジュール
    • 「スケジュールをRunbookにリンクします」
    • 先ほど作成したスケジュールがリストにあるので、それを選択
  • パラメーターと実行設定
    • Runbookのテスト時と同様の値をそれぞれ入力します。

「OK」

Automationアカウントのサイドメニュー→「スケジュール」

先ほど作成したスケジュールを確認。

設定情報のリンクされたRunbookに先ほど設定したRunbookが表示されていれば紐づけ完了。

動作確認

あらかじめ仮想マシンを停止しておく。

  • 設定した日時に仮想マシンの起動を確認
  • ゲームからサーバーに接続確認

接続できれば完了。

おわりに

Palworldサーバーを完全放置の稼働に成功した。

AzureでPalworldのプライベートサーバーを構築した

はじめに

個人のPalworldサーバーを構築した記録

とりあえず構築から常時稼働状態までもっていく。

背景

  • ローカルワールドの招待制だと4人までしかプレイできない。
  • 手軽だが、鯖主は1人プレイの同じデータで遊べるけど、ゲストは初期データから始めなければいけないのがネック。
    • 鯖主だけレベル高い世界みたいなことができやすい?

なので、専用サーバーなら、32人までプレイできるし、フェアにいつでもアクセスできるようにしたかったので構築してみた。

構築概要

AzureでLinux仮想マシンを用意して、そこにPalworldサーバーを構築する。

見積り

まず要求スペックを確認。

https://tech.palworldgame.com/dedicated-server-guide

公式マニュアルを参考すると、

  • CPU:4コア
  • メモリ:16GB

あればいいらしい。

(リリース日は8GBってなってたけど、次の日みたら16GBになってた。ドキュメント更新対応早くてありがたいです。ってかアーリーアクセス時点でこっち系のドキュメントまで整備されているのマジで凄いです。)

予算は月8000円くらいでできるといいなーと思いつつAzureで見積り。

VirtualMachineは、ワークロードの例としてゲームサーバーの記載があったので、D系のシリーズを使うことにします。(D***の細かい文字列は知らん)

スポットVMを使用して価格を抑えます。

Azure料金計算だとスポットのシミュレーションは入っていないっぽいので、正規の値段からスポット価格表を照らし合わせてざっくり計算します。

ストレージはSSDの32GBにしてみた。

130$くらいだから、今の円だとおおよそ1.5倍で2万?

スポットの割引を確認して90%の節約らしいから10分の1で月2000円。

え、安くね?

しかも夜にしか稼働しない予定なので、もっと安く済むかも・・・?

地域は割引考えると近くてもいいと判断し、日本にする。

下記の環境を構築する予定

  • OS:LinuxUbuntu
  • VirtualMachine:4コア、メモリ16GB
  • ストレージ:SSD(32GB)
  • 地域:日本のどこか

構築作業

Azureの管理ページを開いて、Virtual Machines→

作成→Azure仮想マシン

  • プロジェクトの詳細
  • インスタンスの詳細
    • 仮想マシン名:<任意の名前>
    • 地域:(Asia Pacific)Japan East
    • 可用性オプション:インフラストラクチャ冗長は必要ありません。
    • セキュリティの種類:トラステッド起動の仮想マシン
    • イメージ:Ubuntru
    • アーキテクチャ:x64
    • AzureSpot割引を実行する:チェック
    • サイズ:任意のスペックを選択

    ここはvCPUのコア数が3までしか選択できなくて、4にするためには、クォータ要求をする必要があった。

    任意のVMサイズを選んでクォータ要求を送信する。

    自分の場合は10分くらいですぐ承認された。

    (*筆者は見積と同じVMサイズは選択していない。)

  • 管理者アカウント
    • 今回はSSH鍵認証で
  • 受信ポートの規則
    • パブリック受信ポート:選択したポートで接続する
    • SSH(22)
  • ディスク
    • Standard SSD
    • サイズ:規定量(30GiB)
    • VMと共に削除:チェック
    • 他そのまま
  • ネットワーク
    • 仮想ネットワーク:新規作成
    • VMが削除された時にNICを削除する:チェック
    • 他そのまま
  • 管理
    • 自動シャットダウン:チェック
      • 夜更かし防止にテキトーに深夜の時間に設定
  • 監視
    • アラート:チェック
      • 自動シャットダウンの通知確認用

認証をSSHにしたので秘密鍵は忘れずにダウンロードしておく。

これで作成完了

設定(Azure側)

ポート設定

Palworld公式マニュアルより、ポート番号8211を開放します。

仮想マシンのネットワーク設定画面へ進み、ネットワーク設定を行う。

先ほど作成されたネットワークセキュリティグループのポートルールの作成(受信)

UDPプロトコルで宛先のポート番号を指定。

DNS名設定

仮想マシンの作成と一緒に作成された、パブリックIPアドレスの画面へ遷移→構成

DNS名ラベル(オプション)に任意の名前を設定。

「xxxxxx.japaneast.cloudapp.azure.com」のxxxxxxの部分の名前が付けられます。

これでOK

設定(仮想マシン側)

Azure側で仮想マシンを開始しておく。

任意のターミナルソフトでSSH接続し、秘密鍵でログイン。(私はTeraTermを使用)

初期設定

ルートユーザになって、システムを最新にしてみる。

$ sudo -s
# apt update
# apt -y upgrade

導入作業

ここからは、またPalworld公式マニュアルを参考に導入していく。

SteamCMDの導入

  • 公式手順

https://developer.valvesoftware.com/wiki/SteamCMD#Linux

steamユーザを用意する

sudoも使えるようにしておきます。

$ sudo useradd -m steam
$ sudo passwd steam
$ sudo usermod -G sudo steam

SteamCMDのインストール(今回はリポジトリから導入)

$ sudo -u steam -s
$ cd /home/steam
$ sudo add-apt-repository multiverse; sudo dpkg --add-architecture i386; sudo apt update
$ sudo apt install steamcmd

steamcmdコマンドが使用できるようになります。

専用サーバーのダウンロードと準備

公式マニュアルの手順に戻り、進めていく。

専用サーバーのダウンロード

$ steamcmd +login anonymous +app_update 2394010 validate +quit

ダウンロード先のディレクトリは下記のはず

「/home/steam/.steam/SteamApps/common/PalServer/」

一度、サーバー起動スクリプトを実行する。

$ cd ~/.steam/SteamApps/common/PalServer/
$ ./PalServer.sh

ライブラリファイルがないと言われてエラーが出るので、指定の場所にコピーします。

$ mkdir -p ~/.steam/sdk64/
$ steamcmd +login anonymous +app_update 1007 +quit
$ cp ~/.steam/SteamApps/common/Steamworks\ SDK\ Redist/linux64/steamclient.so ~/.steam/sdk64/

再度サーバースクリプトを実行して確認。

$ ./PalServer.sh

起動時に1度エラーが表示され、.steam/sdk64/steamclient.so OK. (First tried local 'steamclient.so')

が表示されることを確認できれば、完了。

動作確認

Palworldを起動して、「マルチプレイに参加する(専用サーバー)」を選択

画面中央下の入力バーに接続先をポート番号付きで入力して接続。

xxxxxx.japaneast.cloudapp.azure.com:8211

キャラ作成画面が表示されれば成功!

楽しんで。

おわりに

これで、いつでも遊びたいときに入って抜けれる環境が構築できた。

引き続き、サーバーの稼働時間の調整や、このワールドの設定やコマンドなどを使ってカスタマイズしていこうと思う。