Open6

CS2サーバーをプラグイン無しで管理する方法を模索する

FlowingSPDGFlowingSPDG

こんばんは。ふろーです。
先日、Project Deusというプロジェクトを発表しました。
CS2の試合サーバー管理、試合結果の登録・参照、BANリストの共有などの機能を持つことを目標とした、サーバー側プラグイン不要で動く統合管理システムです。まだ設計段階ですが。
https://github.com/FlowingSPDG/ProjectDeus

FlowingSPDGFlowingSPDG

余談ですが、Project...と話題になっているのは、公開されてないものを含めいくつかシリーズがあります。
2019年頃にCSGOをプレイされていた方ならご存知かもしれませんが、CSGOの日本コミュニティ主催の「宴」というリーグにて、試合の自動ホスティングシステムに"Project Hypnos"、自動試合放送システムを"Project Talos"と命名し運用していました。
また、2022年頃にも"Project GIARS"という名称にて、CSGOの大会運営を自動化するシステムを運用していました。すべてCSGOに関連するプロジェクトですが、かなりクローズドな用途かつオープンソースではありませんでした。
(Hypnosのみ、コードが綺麗にリファクタリング出来たら公開するという目標がありましたが、綺麗にしている途中にCS2が発表されたので流れました)
(TalosはHLAEにmirv_pgl コマンドが再追加されたら公開するかもしれません。多分。)

FlowingSPDGFlowingSPDG

なぜわざわざこれを作ろうと思ったかというと、僕が制作しているOSSのget5loaderと、それの誕生経緯が大きく関係しています。
https://github.com/FlowingSPDG/get5loader

get5loader自体は、試合の管理を行うマッチプラグイン「get5」と連携するシステムです。
数年前に開発停止してしまったのですが、get5-webというシステムのコンセプトがイケていたため、リメイクプロジェクトのget5-web-go、そして独自路線に切り替えてイチから作り直したget5loader、という風に生まれ変わったという経緯です。

そして、CS2のアップデートでSourceMod自体が使えなくなり、SourceModの上に成り立っているget5も同様に使えなくなったため、大学時代から研究していたOSSが一発で無価値となってしまいました。

FlowingSPDGFlowingSPDG

その後、SourceModの非対応化に伴い、CS2は独自のプラグインシステムの開発が進んだり、プラグイン不要で試合を管理出来るシステムのeBotが再度注目されるなど、大きな変化がありました。
ただし、eBotはかなり古い仕組みであること、シンプルな仕組みのわりに必要なものが多いなど、設計的にあまり気に入らない点がかなり多かったため、eBotを参考にしつつ、get5-webのような使いやすさ、SourceBansのような管理者に優しい機能を提供する管理システムとして、自動的な試合管理を行うシステム構想・実証実験として"Project Deus"の開発に着手することにしました。

FlowingSPDGFlowingSPDG

まずはeBotのような、試合サーバーのログ出力をHTTPで受け取り、正規表現を使ってパースしてイベントとして処理する仕組みを実装します。
幸い、CSGO時代からその仕組みをGo言語で実装している方が、cs2-log というログパーシングパッケージを開発されていたので、ある程度自分でもコントリビュートしたうえで使わせていただきました。

https://github.com/janstuemmel/cs2-log

https://github.com/FlowingSPDG/cs2-log-http

この際、一つ問題がありました。
試合サーバーからHTTPリクエストを受け取る際に、それが本当に試合サーバーから来たリクエストなのか、検証する方法がありません。
通常であればHTTPヘッダーを載せたりして検証することが出来ますが、CS2サーバーの仕様で特定のヘッダーを弄ったりなど認証機能を載せることが出来ませんでした。
代替として考えた機能が以下です。

  • ログに関連するリクエストのみ、ローカルからのアクセスに制限する
    • nginxやVPCなど、別途ツールをかます必要が出てくる?
  • 送信元IPアドレスを確認し、ホワイトリスト判定を実施する
    • 同一のIPアドレスで複数の試合サーバーがホストされている場合、認証が難しくなる
  • 試合サーバーごとにIPアドレスを設定し、送信元IPアドレスに基づいて試合サーバーを特定する
    • ドメイン名で設定した場合(localhost/127.0.0.1) に同一サーバーだと判定するのが煩雑
    • ユーザーから見えるIP(グローバルIP)と実際の送信元IPが異なる場合、同一の試合サーバーだと断定出来ない(想定されるパターンとしては、試合サーバーとProject Deusを同一のVPC中で実行した場合など?)

現在は一番最後のアプローチを考えていますが、あまりスマートなやり方ではないな、と思いながら実装を進めています。
CS2公式でヘッダーを載せる機能がなどが出てくれたら嬉しいのですが...いったんはこの形で行きます。

FlowingSPDGFlowingSPDG

Thiryさんより、「logaddress_token_secretを設定すればHTTPヘッダーを使って認証が出来るのでは」とご指摘頂きました。
https://twitter.com/thiry_sk/status/1728094082327777765

最初cvarの説明を見た際には"UDPパケットの場合に適用"と書いてあったので軽く見逃していたのですが、Valve公式のメジャー大会向けガイドラインにも同じ記述があるため、確認してみます。
https://developer.valvesoftware.com/wiki/List_of_Counter-Strike:_Global_Offensive_console_commands_and_variables
https://github.com/ValveSoftware/counter-strike/blob/main/major-supplemental-rulebook.md#before-each-match