Left 4 Dead 2 Ubuntuを用いたサーバの建て方
Left 4 Dead 2 DedicatedサーバをUbuntu上で動かす方法です。
別でUbuntuマシンがある場合でもほぼ同様の方法でできますが、今回はゲームを行うマシンと同一のWindowsマシンで動かす都合上仮想マシンを使います。
構築方法のベースはWindowsでも同じなため、Modや入り方、設定などはWindows版の記事も一緒です。
こっちは執筆した時期的にも加筆がいくつかありますが。

最終更新日: 2021/10/31



はじめに

仮想マシンを利用することについて

今回はUbuntu Serverを個別のマシンではなく、ゲームを動かすWindows機上に仮想マシンを用意して動作させます。
WindowsマシンやUbuntuマシンが別で存在する場合はそれを使えば良いのですが、同一マシンで動かす場合はリソース云々以前になぜかローカルネットワーク内でもサーバに入れない現象が多発します。
めんどくさくて確認まではしてませんが、L4D2クライアントがポートを占有しているのか、Dedicatedサーバを起動するとログインしているSteamでL4d2が起動したり、いろいろ合わさってうまく動かないのかも。

そんなわけで7dtdとは異なる理由で仮想化します。
7dtdでも書きましたが、3Dアクセラレーションを使うわけではないのでVMware Workstation PlayerでなくてもHyper-VでもDockerでも動くと思います。
ただし、ネットワーク絡みの問題は自己解決をお願いします。

検証環境


ホストマシン
項目 詳細
OS Windows 10 Pro x64
CPU Intel Core i5 4590
Memory 24GB
GPU NVIDIA GeForce GTX 1070
Virtual VMware Workstation Player

ゲストマシン
項目 詳細
OS Ubuntu Server 18.04 LTS 64bit
CPU Intel Core i5 4590 1 core 割当
Memory 2GB

CPUによってはSteamCMDが動作しませんのでご注意ください。
こちらで確認したものだと、Raspberry Pi 4のARMプロセッサでは動作しませんでした
64bit OSではそもそも必要パッケージが入らないので完全にダメで、32bit OSでもパッケージはあれどSegmentation faultで全く動作しなかったのでおそらくARMは完全にダメだと思います。


VMware Workstation Playerの設定 (必要なら)

仮想マシンの作成

今回はUbuntu Server 18.04 LTS 64bitを用いますが、Desktopでも構いません。
ただし、Desktopはメモリ消費もCPU消費も激しいのでServerを強く推奨します。

なお、公式Ubuntuから落とすとめちゃくちゃ遅いのでミラーを使うのをオススメします。
とりあえず理研のUbuntu 18.04を貼っておきます。
Ubuntu 18.04.4 LTS (Bionic Beaver)

仮想マシンの設定

当環境ではこのように設定しています。

CPUもメモリも割当が大きければ大きいほどパフォーマンスに余裕が生まれますが、L4D2サーバはほとんどリソース食わないので1コアでいいかなと。
メモリも確認まではしてませんが、少ないほうなはずなので2GBあれば動きます(多分もっと減らせる)。

また、実メモリに余裕があるなら実メモリを使用するようにしてもいいと思います。
VMware Workstation Playerでは標準で実メモリだけでなくHDD/SSD内部のメモリファイルを使用するので転送速度が遅いとパフォーマンスが下がります。
実際のところそんなに速度低下の影響はないですが、I/OでHDD/SSDの寿命が縮みやすいかもしれないのでちょっと心配。


実メモリを使う場合は.vmxファイルに次の設定を追記/変更を行います。
MemTrimRate = "0"
mainMem.useNamedFile= "FALSE"
sched.mem.pshare.enable = "FALSE"
prefvmx.useRecommendedLockedMemSize = "TRUE"
MemAllowAutoScaleDown = "FALSE"
    
ディスクI/Oが減少しますが、設定した量だけの物理メモリを消費するため、その余裕がない状態だとホストOSごとパフォーマンス低下する恐れがあります。
必ず余裕のある状態で実行するようにしましょう。

ネットワークの設定

ここで重要なのがネットワークの設定です。
通常はNATになっているんですが、これだとサーバ用途としては使用できません
ここでのNATはルータのNAT機能ではなく、ホストマシンがゲストマシンのIPアドレス変換を行うNATとなります。
そのため、ゲストマシンが始点の通信はできても、外部が始点の通信はルータから見えないためただしくポートフォワードできません
L4D2サーバはクライアント(外部)が始点となる通信があるのでこれでは運用ができません。
また、ネットワークスセグメントが異なるためホストマシンからの通信もできません。

ポートフォワードの簡単な仕組みについては7Days To Die サーバの建て方#ポート開放と転送の必要性にて解説しています。

そこでネットワークの設定をブリッジにします。
ブリッジにするとホストマシンにあるNIC(ネットワークインタフェース)と直結し、DHCPのIP割当もルータあるいは専用のDHCPサーバから割り当てされるため、ルータからすると一つの独立したマシンがあるように見えます。(IPv6なら設定次第で外部からも見える)
これによりポートフォワードが可能となるため、外部が始点の通信でもゲストマシンに届くようになります。

前置きはこれぐらいにして、設定は単純にブリッジを選択します。

物理ネットワーク接続の状態を複製は特にネットワーク接続の切り替えがないなら不要です。
合っても特に問題はないかなと思いますが。


あとはアダプタ設定にてブリッジするNICを選択します。
複数ある場合はインターネット接続に使用しているNICを選択しましょう。



Ubuntu Serverでの構築

SSHのインストール

特に必要はありませんが、コマンドのコピペやModを導入する際にあると結構便利です。
また、SFTPはSSHプロトコルを利用するのでファイルのやりとりもこれがあれば簡単にできます。
ただし、サーバの制御ができてしまう上に今回はセキュリティ面の設定を一切行わないため、外部への公開はしないほうが良いでしょう。
ローカルエリアからのみのアクセスを前提とするためご注意ください。

もしセキュリティ面の設定(公開鍵認証方式)も行う場合はRaspberry Pi 4の記事になりますが、同様の設定でできます。
Raspberry Pi 4をサーバ仕様にセットアップする#SSHを公開鍵認証方式に変更する

SSHのインストール自体は簡単で、パッケージからインストールすればすぐに使えます。
$ sudo apt install openssh-server
$ sudo systemctl enable ssh
$ sudo systemctl restart ssh
    

あとはCygwinなどのSSHからユーザ名@ipで接続できます。
$ ssh user@192.168.1.163
    
IPアドレスのチェックは「ip addr show」でできます。
以下の出力例はサーバ設定ごにょごにょしたやつなので異なると思いますが、おそらくeth0かなにかの項目があると思います。
そこにあるinetの値がipv4のローカルIPアドレスとなります。
なお、ipv6の環境はまた異なるので別途検索してください。(ipv6の環境がない)
$ ip addr show
...

4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 9a:07:6d:8d:b9:7c brd ff:ff:ff:ff:ff:ff
inet 192.168.1.163/24 brd 192.168.1.255 scope global br0

...
        

SFTPも同様に22番ポートで接続するとファイルへのアクセスも可能です。
当環境ではWinSCPからSFTPでアクセスしています。


依存パッケージのインストール

i386(32bit)アーキテクチャを追加し、32bitのgccライブラリをインストールします。
なお、Ubuntu 19.10では32bit OS及びパッケージを廃止しているため、いつこれらの提供が廃止されるかわかりません。
といいつつ一部のパッケージのサポートを継続しているようなのでほんとにどうなることやら。
もしかするとタイミングによっては廃止されている可能性もあるのでご注意ください。
その場合はold-releaseなどから引っ張る必要があるかもしれません。

とりあえず執筆当時の2020/03/18では問題なくインストールできました。
$ sudo dpkg --add-architecture i386
$ sudo apt update
$ sudo apt install lib32gcc1
    

SteamCMDのインストール

お次に今回の肝であるSteamCMDをインストールします。 UbuntuではパッケージとしてSteamCMDが配布されていますが、パスが通ってるところにインストールされるわけじゃないので個別にダウンロードして展開するほうがわかりやすいと思います。
確認してないけど、パッケージ版も32bitだから64bit OSだとそもそもないかも知れない。
$ mkdir ~/steamcmd && cd ~/steamcmd
$ wget http://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
$ tar zxvf steamcmd_linux.tar.gz
    

SteamCMDのログインとL4D2サーバのインストール

インストールできたらSteamCMDを起動します。
$ ./steamcmd.sh
                
起動できたらanonymouseでログインします。
なお、個別IDでログインするように説明しているところもありますが、正直めんどいだけなのでanonymousでOK。
Steam> login anonymous
                
ログインできたらL4D2サーバをダウンロードします。
force_install_dirはインストール場所を強制的に変更するコマンドなので特に必要ではありません
変更しない場合はユーザディレクトリ直下にできるSteam/steamapps内部にインストールされます。
app_updateは結構時間かかるので他の作業でもしながら時間を潰しましょう。
また、更新も同様にすることでできます。
Steam> app_update 222860
...
Steam> quit
                

SDL not found

ある日突然SDL not foundとかいうエラーが発生しました。
Failed to init SDL priority manager: SDL not found
                
SDL (Simple DirectMedia Layer)がどうやら存在しないようで、Githubのissueを見るとインストールしてあげれば治るらしい。
ついこの間まで動いてたのになぜ。(多分パッケージ更新せず放置してたからかもしれない)

これが出た場合はlibsdl2をインストールしてあげればOK。
sudo apt install libsdl2-2.0-0:i386
                

サーバ設定

サーバの設定は「~/Steam/steamapps/commons/Left\ 4\ Dead\ 2\ Dedicated\ Server/left4dead2/cfg」内に「server.cfg」を作成し、その中に設定を記述します。

sv_search_keyはサーバ検索で優先的に検索するキーらしく、他人の接続を防止できるらしい。正直効果はわからないし、なんなら接続時に使わない。保険と思っておこう。
sv_allow_lobby_connect_onlyはロビーからの接続のみを許可します。とはいえ、connectコマンドでの接続はできるのでおそらくサーバーリストからの接続を禁止する設定だと思います。

Garry's Modみたいにサーバパスワードで保護できるような機能はなく、とにかくサーバリストからのアクセスや最適な専用サーバからの自動接続を防ぐ他ありません。
現状これでアクセス防止できているので多分大丈夫かな?
とりあえず以下が私が使っている設定項目です。
hostname "Server Name"

# require
sv_search_key "Any Serach Key"
sv_allow_lobby_connect_only 1

# others
mp_disable_autokick 1
sv_alltalk 0
sv_consistency 1
sv_voiceenable 1
sv_region 4

sv_log_onefile 0
sv_logbans 1
sv_lan 0
sv_pure 0
sv_cheats 0

sv_gametypes "coop"
                

サーバ起動

シェルスクリプトを作成するかBashに直打ちで以下のコマンドを入力することで起動できます。
マップ指定はどっちみちロビーから変更するのでダミーです。
./start_srcsd.sh -console -game left4dead2 +maxplayers 4 +exec server.cfg +map c1m1_hotel coop
                
ずらっと文字が流れてしばらくするとサーバが起動します。


ゲームからサーバへ接続

ゲーム内コンソールを有効にする

サーバに接続するには事前にゲーム内コンソールを有効にしておく必要があります。
設定」より、「キーボード/マウス」を開くと「開発者コンソールを許可」という項目があるので有効にします。

この状態で半角全角を押すとコンソール画面が出てきます。

起動時や、開くタイミング次第では日本語入力がオンとなり、超打ちづらいので一回閉じて数秒後もう一度コンソールを開くと英語入力になります。
確か入力欄を右クリックして英語にしても行けた気がしますが憶えてません。

部屋を建てる

L4D2は一般的なゲームサーバと異なり少し特殊です。
サーバ起動時かコマンドでキャンペーンの部屋を建てたいところですが、この時点でキャンペーンなどの部屋はできません。
しかもパスワードをかけれないので入りたい放題です。
そこで前述の設定をした上で、参加者の誰かが接続するサーバをコマンド上で指定した上でロビーを作成することでサーバに接続することができます。
mm_dedicated_force_servers "ローカルIP"
                
今回なら以下のコマンドとなります。
なお、ローカルIPアドレスの確認は「ip addr show」で。
mm_dedicated_force_servers 192.168.1.163
                    

この状態でキャンペーンを選択し、「フレンドと一緒にプレイ」を選択します。

新しいキャンペーンロビーを作成」をクリックします。

サーバのタイプを「最適な専用サーバ」を選択し、いつもどおり部屋を建てます。

あとはゲームを開始するとサーバ側のコンソールが流れだすのでそうすると完了です。
ローカルネットワークからロビーに入るとフレンドを招待することはできますが、ゲームを開始するとフレンドだけ接続できません。
これは招待されたときの情報がローカルIPになっているためにフレンドもローカルIPに接続しようとしてしまうためです。
そのため、ホスト側でゲームを開始した後にフレンドにはゲーム内コンソールからconnectコマンドで直接入ってもらいましょう。
connect グローバルIP
                    
ちなみに、「mm_dedicated_force_servers グローバルIP」とすることで友人に部屋をホストしてもらうことも可能で、この場合はサーバ主だけconnect接続すれば良く、フレンド達はロビーから入れます。
ルータがグローバルIPをローカルIPに変換する機能を持っていたり


ワークショップアドオンの導入

はじめに

こちらからはサーバ拡張作業になります。
必ず必要な手順ではないため省いても問題ありませんが、ユーザーメイドのカスタムマップをプレイする際は必須になるので環境構築だけでもおすすめします。

Python 3のインストール

アドオンのダウンロードに「Steam Workshop Content Downloader」を利用しますが、動作にPythonが必要ですのでインストールしておきましょう。
PythonはWindowsであればインストーラがあるので特にインストールで困るポイントはないと思います。

なぜか3.8でパスが追加されないので環境変数のPATHに追加しておきましょう。(3.7でもされなかったっけ?忘れた)
画像は3.7ですが、デフォルトインストールだと大体同じ場所にあるはずです。


Steam Workshop コレクションを作成する

Steam Workshop Content Downloaderはコレクション単位での管理のみサポートしています。
なのでまずはSteam Workshopにてコレクションを作成します。

まずLeft 4 Dead 2のWorkshopページを開きます。
すると「閲覧する」の中に「コレクション」があるので開きます。

開くと「コレクションの作成」という項目があるのでここでサーバ専用のコレクションを作成します。


設定項目は何でもいいと思います。
サーバで使う以上参加者にも入れて貰う必要があるので共有用としても使うといいでしょう。

Steam Workshop コレクションを作成する

作成したコレクションにアドオンを追加します。
今回は「Yama part 1」を追加してみます。

アドオンのページを開くと「コレクションに追加」ボタンがあるのでクリックします。

するとコレクション一覧が出てくるので作成したコレクションをクリックするとチェックマークが入って追加されます。

ちなみに、他者によってすでにコレクションが作成されている場合はそのまま追加することもできます。
マップ等の場合は複数の必須アドオンをコレクションにまとめてある場合があるので一つ一つやらなくても簡単に追加できます。

例えば、Yamaの場合は「l4d_yama」みたいにコレクションでまとめられています。
なお、コレクションで追加した場合は単体のページでコレクションに追加を開いてもチェックマークが入っていないので注意しましょう。
※コレクションと単体の両方を追加して問題あるかどうかは未検証

コレクションIDの取得

次にコレクションのidを取得します。

まずはコレクションページを開きましょう。
赤枠あたりをクリックするとユーザーページが開きます。

するとコレクションタブがあるのでそれをクリックすると作成したコレクションが出てくるはずです。
見つかればそれを開きましょう。

コレクションページが開くとURLが出てくるので控えておきます。

SteamではデフォルトでURLを表示しない設定になっているので表示するように設定しておくと幸せになれます。
わからなければChromeなどのブラウザでもURLはわかります。



URLがわかればあとはクエリのidパラメータを控えます。
今回は「https://steamcommunity.com/sharedfiles/filedetails/?id=1841176875」なので、「1841176875」ですね。
これがコレクションIDになります。

Steam Workshop Content Downloaderのダウンロード

次に「Steam Workshop Content Downloader」をダウンロードします。
Git管理なのでgitでcloneするなりGithubからそのままダウンロードするなり方法はお好きな方で。
ダウンロード後に、中の「workshop.py」を「~/Steam/steamapps/commons/Left\ 4\ Dead\ 2\ Dedicated\ Server/left4dead2/addons」にコピーします。
ぶっちゃけ場所はここじゃなくてもいいんですが、更新の際にいちいちアドオンのvpkファイルをコピーする必要があって二度手間なのでこうしておくと楽です。

アドオンの新規インストール

コレクションIDがわかればあとはworkshop.pyを実行するだけです。
workshop.pyでは引数にコレクションIDを渡せばコレクションに追加されているアドオンすべてがダウンロードされます。
python workshop.py 1841176875
                
なお、詳しい説明はGithubページに書いてあるのでそちらを一読してください。
ちなみに成功するとこんな感じの出力になります。
> python workshop.py 1841176875
Downloading 372020201.vpk
Downloading complete
Downloading 121086524.vpk
Downloading complete
                    

アドオンの更新

アドオンの更新は単にworkshop.pyを実行するだけです。
python workshop.py
                
具体的には、addons.lstファイルにコレクションIDが入っていればそれを自動的に読み取って更新してくれます。
なので、コレクションにアドオンを新しく追加した場合もこの手順で自動的にダウンロードしてくれます。
ちなみに成功するとこんな感じの出力になります。
> python workshop.py 1841176875
Plugin 372020201 already up-to-date
Plugin 1615944537 already up-to-date
Downloading 121086524.vpk
Downloading complete
                    


SourceModの導入

はじめに

こちらからはサーバ拡張作業になります。
必ず必要な手順ではないため省いても問題ありませんが、より難易度を上げたい場合やチートレベルのModなどのワークショップでは実現できないModが追加できるのでよりカスタマイズしたい場合は導入しましょう。
ちなみに、分かりづらいので項目分けしていますが、Metamodも必要なのでこちらも導入しておきましょう。

SourceModのダウンロードとインストール

ダウンロードは「SourceMod: Half-Life 2 Scripting」より対応のOSを選択するとダウンロードが始まります。
$ mkdir -p ~/mods/sourcemods && cd ~/mods/sourcemods
$ wget https://sm.alliedmods.net/smdrop/1.10/sourcemod-1.10.0-git6490-linux.tar.gz
                

インストールは、ダウンロードしたファイルの中にある「cfg」と「addons」の2つのフォルダを「~/Steam/steamapps/commons/Left\ 4\ Dead\ 2\ Dedicated\ Server/left4dead2」にコピーするだけです。
$ tar zxvf sourcemod-1.10.0-git6490-linux.tar.gz
$ rsync -a cfg/ ~/Steam/steamapps/commons/Left\ 4\ Dead\ 2\ Dedicated\ Server/left4dead2/
$ rsync -a addons/ ~/Steam/steamapps/commons/Left\ 4\ Dead\ 2\ Dedicated\ Server/left4dead2/
                

SourceModプラグインのインストール

プラグインによってインストール方法は異なり、多種多様なので一概には言えませんが、大体は同じなので一つだけ例で出してみます。

今回は「[L4D/L4D2] Infected Health Gauge (Tank & Witch & Special)」です。
こういったプラグインのページを開くと下の方に「Get Plugin」があるのでクリックするとsmxファイルがダウンロードできます。
これを「~/Steam/steamapps/commons/Left\ 4\ Dead\ 2\ Dedicated\ Server/left4dead2/sourcemod/plugins」にコピーします。
これだけです。

ただ、プラグインによっては追加で必要なファイルがある場合があるので説明を読みながら導入するようにしましょう。
中には厄介なプラグインもあって、例えばSuper TanksはGet Pluginを押すとエラーでダウンロードできません。
その場合はGet Sourceを押し、spファイルをダウンロードします。
後はspファイルを「SourceMod Plugin Compiler」に流すとsmxファイルが手に入ります。


Metamodの導入

Metamodのダウンロードとインストール

MetamodもSourceMod同様に「Metamod:Source - Snapshots」より対応するOSを選択すると開始します。

インストールも同様に「addons」フォルダを「steamapps\commons\Left\ 4\ Dead\ 2\ Dedicated\ Server\left4dead2」にコピーするだけです。

metamod.vdfの作成 : オプション

デフォルトで入ってるやつで大丈夫だと思いますが、うまく動かない場合はmetamod.vdfを編集します。
といっても「Make a VDF File」で「Left 4 Dead 2」を選択して生成すれば良いだけなので特に説明はいらないかな。