Linux ゲームサーバーをWEB&Discordで操作(汎用ゲームサーバー管理WEBサーバーの制作)
自前のゲームサーバー立てたことありますか?
自前サーバーというのは、オンライン専用ではないゲームでマルチプレイする場合、接続するサーバーは自分で用意するシステムの事で、有名どころだとマインクラフト(Java版)は自前サーバーですね。
他には"Palworld"や"7 Days to Die"や"ARK"なんかでサーバーを建てた経験があります。
さてさて、こういったゲームで若干問題になるのが、サーバー立てた当人しか開始やシャットダウンできない、起動時にシェルからコマンド打たないといけないなど、専用サーバーにしているならではの問題があります。まぁ専用サーバーじゃなくてホストのセッションに合流形式だともっと厳しいですが…。
今回はこの点、Python使って解決しちゃいましょう。
前提条件
環境
今回の記事で想定される環境は以下とします
Steamで配信されているゲームで、かつSteamCMDでサーバーを構築する際にLinux用のサーバーが用意されているゲームです。
別に環境が違えども、起動スクリプトがあり、それをシェルから実行するサーバーなら何でもOK!
OS:Linux (CentOS7)
自前のPC/レンタルサーバー
SteamCMDでサーバーは用意済み
対象
Linuxを自力で管理できる人Orやる気のある人
Pythonの知識があるOrやる気のある人
システムの構成
システム概要
本システムを一言で説明すると、シェルから起動するタイプのサーバーをWEBサーバーの子プロセスとして実行して管理する。
WEBへのダイレクトアクセスと別途用意するDicord BOT連携操作の2種類の操作方法を設ける。
最小構成 : Flaskサーバーのみ
Discord BOT連携 : Flaskサーバー & DiscordBOT
メインシステム
Flask WEBサーバー
各ゲームサーバーを"threading"ライブラリで子プロセスとして起動させる。
サーバー管理者はこのサーバーからでもボタンで操作可能。
起動と停止にはそれぞれ専用のスクリプトを作成し、それを起動するようにすることで汎用性を持たせる
サブシステム
Discord BOT
ゲーム参加者が簡単にサーバーの起動とシャットダウンができるように、DiscordのBOTに指示を出すと、BOTがFlask WEBサーバーのCGIにGETで指示を出して操作する。
つまり、チャットで"/cmd start 7daysToDie"みたいな感じで入力するだけでサーバーの起動や停止ができる。
Discordを使う理由
第一に誰でも簡単に制御ができること。チャットで特定のメッセージを送るだけで簡単に操作できます。
また、WEBサーバーにアクセスさせてもいいが、平文通信なのとFlaskは公開向けのライブラリではないのでポート開放して使用するのは少々懸念があります。
しかし、DiscordのBOTなら同じコンピューター内で動作するので、localhostからFlaskに指示を出せばいいので安全です。
こういった理由からDiscordのBOTを使います。
勇者の方はWEBサーバーのポート開けてもいいです…。
使用方法と適用例
今回のシステムは、過去の経験上Linux版のサーバーを出しているゲームなら起動スクリプトから起動できること、終了の方法は別途通信プロトコルを設けていることが多いことが分かっていますので、複数タイトルで使用できるような仕組みで行きます。
後から追加されたタイトルごとの説明は下記をご確認ください
Palworld(パルワールド)の場合
ARKの場合
詳細解説(7 Days to Dieで解説)
本記事は7dtdサーバーを再構築する時点で作成しているため、本作で解説となります。
このセクションは7dtdだけでなく、他のタイトルのサーバーを建てる際に必須な情報も含んでいるため適宜見てください。
このタイトルの場合は、サーバー構築時点で開始するためのスクリプトが作成されているのでそれを使いつつ、シャットダウンはTelnetを使います。
タイトルによってはここがRconだったりしますね。
ちなみにデフォルトでは無効になっているので、以下のようにTelnetを設定を有効にしておいてください。
ちなみにここで話をするのはA21バージョンです。
いつからか、ウェブの管理ターミナルが変わったのか、ただアクセスしただけではシャットダウンができなくなってしまったので、Tenletを使います。仕組みが分かっていれば、そのWEBのAPIに対してシャットダウンのコマンドを投げるような終了スクリプトを書いても大丈夫です。
<!-- Admin interfaces -->
<property name="WebDashboardEnabled" value="true"/> <!-- Enable/disable the web dashboard -->
<property name="WebDashboardPort" value="8081"/> <!-- Port of the web dashboard -->
<property name="WebDashboardUrl" value=""/> <!-- External URL to the web dashboard if not just using the public IP of the server, e.g. if the web dashboard is behind a reverse proxy. Needs to be the full URL, like "https://domainOfReverseProxy.tld:1234/". Can be left empty if directly using the public IP and dashboard port -->
<property name="EnableMapRendering" value="true"/> <!-- Enable/disable rendering of the map to tile images while exploring it. This is used e.g. by the web dashboard to display a view of the map. -->
<property name="TelnetEnabled" value="true"/> <!-- Enable/Disable the telnet -->
<property name="TelnetPort" value="8082"/> <!-- Port of the telnet server -->
<property name="TelnetPassword" value=""/> <!-- Password to gain entry to telnet interface. If no password is set the server will only listen on the local loopback interface -->
<property name="TelnetFailedLoginLimit" value="10"/> <!-- After this many wrong passwords from a single remote client the client will be blocked from connecting to the Telnet interface -->
<property name="TelnetFailedLoginsBlocktime" value="10"/> <!-- How long will the block persist (in seconds) -->
サーバーツールの構成
本ツールの構成は以下のようになっています。
メインのPythonスクリプト及びDiscordのbot用スクリプトで構成されています。
また、それぞれ別途Systemdのサービスに登録しておきます。(しなくてもいいですが)
これは何をしているかというと、Windowsで言うスタートアッププログラムの登録です。サーバーの電源を入れた時に、Webサービスとボットが立ち上がります。
Systemdに関しては本ツールを作るにあたり、以下でメモしたのでご確認ください。
サーバー定義の作成
構成フォルダ内のserversのフォルダがサーバー構成を作成するフォルダになります。
この中に各ゲームごとのサーバー定義管理用のフォルダを作成します。
各記事で個別にこのツール内の定義方法を説明している場合、ここから先のセクションの話となります。
さらに、その中にはスタート、ストップ、アップデート、バックアップの4
つのスクリプトを入れます。
なお、最低スタートとストップがあればよいです。
start.sh
サーバーを開始するシェルスクリプトです。管理サーバーからこのスクリプトを引数なしで起動して、ゲームサーバーが立ち上がるように中身を記述します。
このスタートスクリプトのポイントはいくつかあります。
まず一つ目、20行目が実際のサーバーを起動するための行になります。
シェルスクリプトの中で既存のゲームサーバーを起動するためのスクリプトを呼び出しているという形になります。
次のポイントは二重起動を防ぐためのブロックです。
起動時にstat.txtという名前のテキストファイルを出力し、終了したらそのファイルを削除することで、二重起動をしないようにブロックするような機構を設けてあります。
そのため、実際にこれをコピペして使う場合は起動スクリプトの行だけを変更することになります。
stop.sh
サーバーを停止するためのスクリプトです。ゲームの仕様に応じて最適な方法で停止させるように記述します。
7 Days to Dieの場合は上記のようになります。
終了コマンドは"shutdown"で、それをtelnet経由で送信します。
Cent OSにはデフォルトでtelnetが入っていないので別途インストールしておいてください。
実際にサーバーを立てた後、一旦上記のスクリプトを実行してサーバーが停止することを確認してみることをお勧めします。
update.sh
こちらは手動で流しただけで、まだ未検証ですが中身だけ紹介します。
基本的にSteamCMDでのアップデートをそのまま書き込んだだけです。
ただし、アップデート中に起動されると困るので、ブロックファイルであるupdate.txtを出力するようにしています。
backup.sh
ボタン一つでセーブデータをバックアップするためのスクリプト
この例では、保存フォルダの中身をZIPに圧縮して専用のフォルダーに格納する手順となっています。名前はその日の日付で出来上がります。
操作方法
では、実際にサーバーの起動と終了をやってみましょう。
先ほどのサーバー定義を作成したら、プログラムを再起動してください。そうすることでサーバー定義が読み込まれます。
起動方法
最小構成
GameServer_WEB.pyを起動
メインのFlaskWEBサーバーです。これは必須です
Discord連携
GameServerbot.pyも起動
連携のBotです。
Linuxでの起動方法は下記の通りです。
systemdへの登録をしたくない場合はnohupを使うことでシェルからログアウト後も実行できます。
動作確認だけの場合
$ python3 GameServer_WEB.py
$ python3 GameServerbot.py
systemdを使わずに立ち上げる場合
$ nohup python3 GameServer_WEB.py &
$ nohup python3 GameServerbot.py &
WEB操作パネルから操作
管理者であれば一番分かりやすいのがこのWebコントロールパネルです。
サーバー定義のフォルダ名がサーバー名となり、ステータス及び操作ボタンが表示された手抜ry…シンプルなものです。
というわけで、操作方法は簡単!!起動/停止ボタンを押すだけです。
もうお分かりかと思いますが、このボタンを押すことでstart.sh/stop.shが呼び出される仕組みです。
WEBへのアクセス方法はデフォルトの場合25564ポート(マイクラ-1)にしています。IPアドレス等はLinuxで建てる時点で大丈夫ですね。
他にアップデートとバックアップについても、各サーバーの横にあるボタンを押すことでスクリプトを呼び出すことができます。
Discordからの操作
次はDiscordをチャットで操作する方法を見ていきましょう。
なお、すでにBOTアカウントを作成&サーバーに招待済みで、本ツールのDiscord.pyを立ち上げると、BOTが立ち上がるようになっている前提です。
トークンはスクリプト内に書くところがあります
BOTの作成方法は下記メモを確認してください
全般
本ツールのBOTは"サーバー管理"という名前のチャンネルに対して反応します。必ず作成してください。
コマンド方式
/コマンド 引数ヘルプ
/help
上記コマンドを入力することで、どんなコマンドが使えるのか、それはどういうものなのかの説明をしてもらえます。
操作コマンド
list
現在管理されているサーバーとそれらのステータス一覧を表示します。start サーバー名
ゲームサーバーを起動しますstop サーバー名
ゲームサーバーを終了しますupdate サーバー名
ゲームサーバーをアップデートしますbackup サーバー名
セーブフォルダをバックアップします
システム操作コマンド
shutdown
サーバー本体をシャットダウンします。身内で「最後の人電源切っといて」という使い方をする前提のコマンドです
※ルート権限が必要なので、RootでSystemd起動している場合のみ機能します
exit
Botを終了します。
ツールの配布について
以下よりツールを配布します。
詳細なコードが気になる方もぜひDLしてみてください。
アップデート情報
アップデートでの変更は記事にはサイレント反映されますので、具体的な変更内容はここで記載します。
Ver 1.0.0 2023/08/13 初版
Ver 1.1.0 2024/01/28 Palworld記念アップデート
BOTシステム
サーバーとチャンネルの取得方法を変更
これにより、"サーバー管理"という名前のチャンネルを用意する必要があります。コマンドの形式を変更
exitコマンド追加
まとめ
今回はゲームサーバー管理サーバーを作成しました。
過去にマイクラサーバー管理ツールなら作ったことがあるのですが、あれはマイクラに特化しすぎて他では使えないものになってしまいました…。
今回は起動や停止に任意のスクリプトを作成できる仕組みにしたことで、汎用性を持たせました。
また、操作方法にWEBサーバーと参加者向けのDiscordチャット機能を追加し、電源さえ入っていれば最初に始めたい人が点けることができるようになり、最後の人がシャットダウンまで行えるようになりました。
電源投入に関しては、電気代の都合上メインマシンの電源を入れてはおけませんが、BOT側にラズパイ等を使用してWOLパケットを投げられるようにするなんてのもいいかもしれませんね。そこまですれば管理者はサーバーを建てる作業さえすれば参加者が自由にプレイ可能ですね。