<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Steam on kymt.me</title><link>https://kymt.me/tags/steam/</link><description>Recent content in Steam on kymt.me</description><generator>Hugo</generator><language>ja</language><lastBuildDate>Mon, 06 Feb 2012 00:00:00 +0000</lastBuildDate><atom:link href="https://kymt.me/tags/steam/index.xml" rel="self" type="application/rss+xml"/><item><title>ruby-qstat</title><link>https://kymt.me/projects/ruby-qstat/</link><pubDate>Sat, 04 Feb 2012 00:00:00 +0000</pubDate><guid>https://kymt.me/projects/ruby-qstat/</guid><description>&lt;p&gt;ゲームサーバー統計取得ツールの &lt;a href="https://qstat.sourceforge.net/"&gt;QStat&lt;/a&gt; を Ruby から使うためのラッパー gem です。qstat コマンドを起動して、マスターサーバーからのサーバー一覧取得や、個別のゲームサーバーへの状態問い合わせの結果を、Ruby のオブジェクトとして返します。&lt;/p&gt;&#10;&lt;p&gt;README 記載の動作要件は Ruby 1.9 と QStat 2.12 です。&lt;/p&gt;&#10;&lt;h2 id="使い方"&gt;使い方&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gem install ruby-qstat&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;README にある例です。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# マスターサーバーからサーバー一覧を取得&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="no"&gt;QStat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query_serverlist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;hl2master.steampowered.com:27011&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;stm&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;left4dead2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maxping&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 個別サーバーの状態を取得&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="no"&gt;QStat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;xxx.yyy.zzz.qqq&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;a2s&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 個別サーバーの状態を取得(サーバー情報のみ)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="no"&gt;QStat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query_serverinfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;xxx.yyy.zzz.qqq&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;a2s&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="内部設計"&gt;内部設計&lt;/h2&gt;&#10;&lt;p&gt;ライブラリ本体は &lt;code&gt;lib/ruby-qstat.rb&lt;/code&gt; の1ファイルで、API は &lt;code&gt;QStat&lt;/code&gt; クラスのクラスメソッド群として提供します(インスタンス化はできない作りです)。qstat コマンドの起動は共通の &lt;code&gt;exec_cmd&lt;/code&gt; に集約されていて、出力の形式によってパース経路が2系統に分かれます。&lt;/p&gt;&#10;&lt;p&gt;&lt;span class="diagram-scroll" role="group" tabindex="0" aria-label="ruby-qstat のコンポーネント構成図"&gt;&lt;img src="https://kymt.me/projects/ruby-qstat/internals.svg" alt="ruby-qstat のコンポーネント構成図"&gt;&lt;/span&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;exec_cmd&lt;/strong&gt; — &lt;code&gt;Open3.popen3&lt;/code&gt; で qstat を起動し、stdout を読むスレッドと stderr を Logger に流すスレッドの2本で出力を回収します。filter ブロックを渡すと、stdout を1行読むごとに判定して、条件が成立した時点で qstat プロセスを &lt;code&gt;TERM&lt;/code&gt; で打ち切れます。qstat のパスは &lt;code&gt;QStat.qstat_path=&lt;/code&gt;、ロガーは &lt;code&gt;QStat.logger=&lt;/code&gt; で差し替えられます&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;XML 系&lt;/strong&gt;(&lt;code&gt;query_serverlist&lt;/code&gt;/&lt;code&gt;qslist&lt;/code&gt;)— &lt;code&gt;-xml&lt;/code&gt; オプション付きで起動して、出力を Nokogiri でパースします。&lt;code&gt;Response&lt;/code&gt; オブジェクトが XML と DOM を保持し、&lt;code&gt;valid?&lt;/code&gt;(先頭の server 要素の status が UP か)や &lt;code&gt;to_ror&lt;/code&gt;(ActiveSupport の &lt;code&gt;Hash.from_xml&lt;/code&gt; によるハッシュ化)を提供します&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;テキスト系&lt;/strong&gt;(&lt;code&gt;query&lt;/code&gt;/&lt;code&gt;query_serverinfo&lt;/code&gt;)— &lt;code&gt;-P&lt;/code&gt;(プレイヤー情報)・&lt;code&gt;-R&lt;/code&gt;(サーバールール)付きのプレーンテキスト出力を正規表現でパースして &lt;code&gt;ServerInfo&lt;/code&gt; を作ります。「no response」「DOWN」の応答もヘッダ行の正規表現で判定します&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;結果オブジェクト&lt;/strong&gt; — &lt;code&gt;ServerInfo&lt;/code&gt;(アドレス・サーバー名・マップ・人数・ping・status など)、&lt;code&gt;PlayerInfo&lt;/code&gt;(名前・frags・プレイ時間。qstat の「1h 2m 3s」のような時間表記を秒に換算するパーサ入り)、&lt;code&gt;Rule&lt;/code&gt;(protocol・gamedir・secure・version・game_tag などのサーバールール)。&lt;code&gt;ServerInfo#playing_time&lt;/code&gt; は、いちばん長くプレイしているプレイヤーの時間を返します&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;ゲームタイプ推定&lt;/strong&gt; — &lt;code&gt;ServerInfo#suggest_game_type&lt;/code&gt; は、gametype が取れなかったときにサーバールールの game_tag(&lt;code&gt;@&lt;/code&gt; 以降のカンマ区切りタグ)から推定し、それもなければ &lt;code&gt;unknown&lt;/code&gt; を返します&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;文字コード対策&lt;/strong&gt; — qstat には常に &lt;code&gt;-utf8&lt;/code&gt; を付け、さらに &lt;code&gt;String#force_convert_to&lt;/code&gt;(UTF-16BE を経由して不正なバイトを &lt;code&gt;?&lt;/code&gt; に置換してから戻す monkey patch)で、サーバー名などに混ざる壊れたバイト列を無害化します&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;サーバー一覧取得(&lt;code&gt;query_serverlist&lt;/code&gt;)の流れです。maxping を超えるサーバーが現れた時点で qstat を打ち切る作りで、途中で切れた XML はそのまま Nokogiri に渡してパースします。&lt;/p&gt;</description></item><item><title>vrowser</title><link>https://kymt.me/projects/vrowser/</link><pubDate>Mon, 06 Feb 2012 00:00:00 +0000</pubDate><guid>https://kymt.me/projects/vrowser/</guid><description>&lt;p&gt;Left 4 Dead 2 や Team Fortress 2 など、HalfLife2 系(Source Engine)ゲームのサーバーブラウザを作るための Ruby ライブラリです。ゲームサーバー統計取得ツールの &lt;a href="https://qstat.sourceforge.net/"&gt;QStat&lt;/a&gt; をラップして、サーバー一覧の取得・データベースへの記録・JSON API での配信までを一式でやります。&lt;/p&gt;&#10;&lt;p&gt;gem として公開していて、コマンドラインツールも同梱しています。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gem install vrowser&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;vrowser sample &lt;span class="c1"&gt;# サンプル設定ファイルを生成&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;vrowser -f config.yml fetch &lt;span class="c1"&gt;# マスターサーバーからサーバー一覧を取得&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;vrowser -f config.yml update &lt;span class="c1"&gt;# 登録済みサーバーの状態を更新&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;vrowser -f config.yml daemon &lt;span class="c1"&gt;# 常駐デーモンとして起動&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="内部設計"&gt;内部設計&lt;/h2&gt;&#10;&lt;p&gt;コンポーネント構成です。中核の &lt;code&gt;Vrowser&lt;/code&gt; クラスが QStat の呼び出しと Sequel(ORM)経由の DB 記録を束ねていて、CLI・常駐デーモン・Sinatra アプリのどこからでも同じ処理を呼べる作りになっています。&lt;/p&gt;&#10;&lt;p&gt;&lt;span class="diagram-scroll" role="group" tabindex="0" aria-label="vrowser のコンポーネント構成図"&gt;&lt;img src="https://kymt.me/projects/vrowser/internals.svg" alt="vrowser のコンポーネント構成図"&gt;&lt;/span&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Vrowser&lt;/strong&gt;(&lt;code&gt;lib/vrowser.rb&lt;/code&gt;)— &lt;code&gt;fetch&lt;/code&gt;(マスターサーバーからサーバー一覧を取得して DB に登録)、&lt;code&gt;update&lt;/code&gt;(登録済みサーバーを全件クエリして状態更新)、&lt;code&gt;clear&lt;/code&gt;(DOWN したサーバーの削除)を提供します&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;VrowserModel::Servers&lt;/strong&gt; — Sequel のモデル。スキーマ定義もコード内に持っていて、テーブルがなければ初回接続時に作ります。&lt;code&gt;host&lt;/code&gt; カラムが unique キーです&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Vrowser::HTTPDaemon&lt;/strong&gt;(&lt;code&gt;lib/vrowser/http_daemon.rb&lt;/code&gt;)— WEBrick で JSON API(&lt;code&gt;/api/updated/json&lt;/code&gt;・&lt;code&gt;/api/connected/json&lt;/code&gt;)と &lt;code&gt;public_html/&lt;/code&gt; の一覧 UI(jQuery DataTables 製)を配信しつつ、別スレッドで取得ループを回します&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;plugins/&lt;/strong&gt; — ゲーム別の追加ロジック。同梱の &lt;code&gt;l4d2.rb&lt;/code&gt; は、サーバー情報からゲームタイプが判定できないときにサーバー名の正規表現マッチ(&lt;code&gt;co-?op&lt;/code&gt;、&lt;code&gt;versus&lt;/code&gt;、&lt;code&gt;scavenge&lt;/code&gt; など)でゲームタイプを推定します&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;デーモンの更新サイクルはこうなっています。マスターサーバーへの問い合わせは重いので、一覧の再取得は約30分に1回、その間は登録済みサーバーへの個別クエリ(A2S)を150秒間隔で回す二段構えです。&lt;/p&gt;</description></item><item><title>SQCN</title><link>https://kymt.me/projects/sqcn/</link><pubDate>Mon, 06 Jun 2011 00:00:00 +0000</pubDate><guid>https://kymt.me/projects/sqcn/</guid><description>&lt;p&gt;Steam のユーザー名(表示名)をワンクリックで切り替えるためのツールです(&lt;strong&gt;S&lt;/strong&gt;team &lt;strong&gt;Q&lt;/strong&gt;uick &lt;strong&gt;C&lt;/strong&gt;hange &lt;strong&gt;N&lt;/strong&gt;ame の略)。よく使う名前を登録しておいて一覧から選んで適用できます。C#/.NET Framework 製。&lt;/p&gt;&#10;&lt;h2 id="機能概略"&gt;機能概略&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;適用: 選択された名前に変更します&lt;/li&gt;&#10;&lt;li&gt;すべて適用: 配信の視聴者参加用(普段の名前の履歴を見せないため)。設定された名前すべてに一度変更してペルソナ履歴を消します(10個あれば履歴完全に消えます)&lt;/li&gt;&#10;&lt;li&gt;履歴消去: 過去に使った名前を他人から見えないようにするため、ペルソナ履歴を1から10の数字で上書きします(「すべて適用」と同じ目的)&lt;/li&gt;&#10;&lt;li&gt;通常オフラインだと名前変更できないが、このツールだとオフラインのまま名前変更できる(ゲームに入る前に名前を決めておくため)&lt;/li&gt;&#10;&lt;li&gt;標準の UI からだと1文字の名前に変更できない(最低2文字必須)が、このツールだと可能&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;いずれも Steam の表示名を自分で設定し直すだけの機能で、変更できるのは自分のアカウントの表示名だけです。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Steam を起動している状態で実行する必要があります。&lt;/strong&gt; なお、なんか Steam のアップデートでうまく動かなくなったので放置中です。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="https://assets.kymt.me/gaming/misc/SQCN.png" alt="SQCN のスクリーンショット"&gt;&lt;/p&gt;&#10;&lt;h2 id="ダウンロード"&gt;ダウンロード&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://assets.kymt.me/gaming/misc/SQCN_20110606_2.zip"&gt;SQCN(2011/06/06)&lt;/a&gt;&lt;/p&gt;</description></item><item><title>GetFriendAvators</title><link>https://kymt.me/projects/getfriendavators/</link><pubDate>Tue, 24 May 2011 00:00:00 +0000</pubDate><guid>https://kymt.me/projects/getfriendavators/</guid><description>&lt;p&gt;Steam のすべてのフレンドのプロフィールアイコン(大きい方)を取得して、まとめて保存するツールです(デフォルトの ? アイコンの人がいればそれも取得可能)。&lt;/p&gt;&#10;&lt;p&gt;Open Steamworks + Windows .NET の習作として作りました。Steam を起動している状態で実行してないとエラーで落ちます。&lt;/p&gt;&#10;&lt;h2 id="ダウンロード"&gt;ダウンロード&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://assets.kymt.me/gaming/misc/GetFriendAvators_20110524.zip"&gt;GetFriendAvators(2011/05/24)&lt;/a&gt; (&lt;a href="https://assets.kymt.me/gaming/misc/getfriendavators_ss.png"&gt;スクリーンショット&lt;/a&gt;)&lt;/p&gt;&#10;&lt;p&gt;→ &lt;a href="https://gist.github.com/986866"&gt;ソースコード (gist)&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>