こんにちは、山本です。

さて、みなさんはSteamというものをご存知でしょうか?

簡単に言ってしまうと、海外のPCゲームのダウンロード販売サービスです。

特徴としては、ゲームの安さでしょうか。

まず、サマーセール、ウインターセール等といった、季節ごとに規模の大きいセールがあり、セール期間中はゲームによってまちまちですが、価格が25~75% offで販売されています。
ものによってはそれ以上の割引を行っているものすらあります。

セールは季節だけではなく、週末や、週の中にもあったり、年中何かしらのセールを行っています。

その為、セール中に安いのでとりあえず買っておいて、後でやろうと思いつつ、一度もプレイせずといったことが積み重なり、積みゲーが増えていくわけですね。

人によってですが、「買おうと思ってカートに入れようとすると、もう既に買っていた」、「セールの度に欲しいゲームが増えていく」等などといった現象もあるようです。

因みにですが、「Steamでは所有ゲームの37%が積みゲーである」といった統計もあります。
http://www.gamespark.jp/article/2014/04/17/47914.html

積みゲーを調べる

SteamにはWeb APIが用意されています。

これを使って積みゲーを調べてみましょう。

ドキュメントを見てみると、ニュースの一覧取得、ゲームの詳細情報、フレンドリストの取得、ユーザの所持ゲーム取得等などのAPIが用意されています。

所持ゲームと、ゲームの詳細情報あたりがあれば、積みゲー率を調べることが出来そうですね。

All interfaces and method are self-documented through the ISteamWebAPIUtil/GetSupportedAPIList call. This can be found here.
When passed a key= parameter, GetSupportedAPIList will show all APIs that your key can access. Without it (as above), it only displays APIs that do not require an API key.

APIキーがないと、APIは使わせないよと仰っています。

  • APIキーを取得する

ですので、キーを取得しましょう。

早速、ブログ用にアカウントを作成してAPIキーを取得します。

steam_001

……ゲームがないアカウントではキーは取得出来ないそうです。
この記事は会社で作成しているので、できれば私物のアカウントを使用するのは避けたいのですが……。

しかたがないので、フリーゲームをライブラリに加えてみましょう。

steam_002

足した状態で、再度APIキーを取得します。

steam_001

どうやらフリーゲームだけでは、Steam様はご満足頂けないようです。

どうやら、スパム対策等で今年の四月から5ドル以上を使用したアカウントのみAPIキーを取得可能となったようです。

http://www.gamespark.jp/article/2015/04/20/56399.html

……仕方がないので、私用のアカウントでキーを取得します。

steam_014

はじめからこうすればよかったですね。

  • 所持ゲームリスト取得する

リストの取得にはGetOwnedGamesを使用します。

では、GetOwnedGamesのパラメータを確認しましょう。

Arguments
  steamid
    The SteamID of the account.
  include_appinfo
    Include game name and logo information in the output.
    The default is to return appids only.
  include_played_free_games
    By default, free games like Team Fortress 2 are 
    excluded (as technically everyone owns them). 
    If include_played_free_games is set, 
    they will be returned if the player has played 
    them at some point. This is the same behavior 
    as the games list on the Steam Community.
  format
    Output format. json (default), xml or vdf.
  appids_filter
    You can optionally filter the list to a set of appids.
    Note that these cannot be passed as a URL parameter, 
    instead you must use the JSON format described 
    in Steam_Web_API#Calling_Service_interfaces. 
    The expected input is an array of integers 
    (in JSON: "appids_filter: [ 440, 500, 550 ]" )

Steam IDが必須なようです。

  • Steam IDを取得する

まず、Steam IDとは何か?から始まるのですが、初めはログイン用のアカウント名なのかとも思いましたが、プロフィール画面のURLに含まれる数字がIDのようです。

  • 再度所持ゲームリスト取得する

http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=xxxxxxxxxxxxxxxxx&steamid=xxxxxxxxxxxxxxxxx

steam_004

JSON形式でリストが取得できました。

レスポンスについて解説すると

game_count the total number of games the user owns (including free games they’ve played, if include_played_free_games was passed)

game_countが保持しているゲームの件数で

playtime_forever The total number of minutes played “on record”, since Steam began tracking total playtime in early 2009.

playtime_forever が2009年以降にプレイしたゲームの時間を分単位で取得できるようです。

Steamで過ごした時間を取得してみましょう。

<?php
require_once 'underscore.php';

$key    = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$userid = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$ret    = json_decode(file_get_contents('http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?'.http_build_query(array('key' => $key, 'steamid' => $userid))), true);


$list = __::sortBy($ret['response']['games'], function ($item){
  return $item['playtime_forever'];
});

krsort($list);

$sum  = 0;
$rows = array();

foreach ($list as $r)
{
  $sum += $r['playtime_forever'];
  $rows[] = '<td>'.implode('</td><td>', array($r['appid'], sprintf('%dh %dm', $r['playtime_forever'] / 60, $r['playtime_forever'] % 60))).'</td>';
}

printf('<p>Total : %dh %dm</p>', $sum / 60, $sum % 60);

echo '<table border="1">';
echo '<tr><th>title</th><th>time</th></tr>';
echo '<tr>'.implode('</tr><tr>', $rows).'</tr>';
echo '</table>';

ゲームごとのプレイ時間と総プレイ時間が取得出来ました。

steam_006

が、AppIDでは何のゲームなのかよく分かりません。

include_appinfo
Include game name and logo information in the output. The default is to return appids only.

パラメータにゲーム名とロゴ情報を追加出力するオプションがあるようなので、それを使います。

<?php
  require_once 'underscore.php';

  $key    = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
  $userid = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

  $ret    = json_decode(file_get_contents('http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?'.http_build_query(array('key' => $key, 'steamid' => $userid, 'include_appinfo' => 1))), true);

  $list = __::sortBy($ret['response']['games'], function ($item){
    return $item['playtime_forever'];
  });

  krsort($list);

  $sum  = 0;
  $rows = array();

  foreach ($list as $r)
  {
    $sum += $r['playtime_forever'];
    $rows[] = '<td>'.implode('</td><td>', array($r['name'], sprintf('%dh %dm', $r['playtime_forever'] / 60, $r['playtime_forever'] % 60))).'</td>';
  }

  printf('<p>Total : %dh %dm</p>', $sum / 60, $sum % 60);

  echo '<table border="1">';
  echo '<tr><th>title</th><th>time</th></tr>';
  echo '<tr>'.implode('</tr><tr>', $rows).'</tr>';
  echo '</table>';

dev.steam.com

ゲームタイトルとそれぞれのプレイ時間が分かるようになりました。

使ってみる

「誰でも使えるようにしてみては?」とのご意見を頂きました。
もっともなことなので、誰でも使えるように調整して設置しました。

/works/steam/488.php

<?php
  require_once 'underscore.php';

  $key    = !empty($_POST['key']) && preg_match('/^[0-9A-Z]{1,}$/', $_POST['key']) ? $_POST['key'] : '';
  $userid = !empty($_POST['userid']) ? (int)$_POST['userid'] : '';
  $rows   = array();

  if ($key && $userid)
  {
    $ret = getApiResponse('http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/', array('key' => $key, 'steamid' => $userid, 'include_appinfo' => 1));

    $list = __::sortBy($ret['response']['games'], function ($item){
      return $item['playtime_forever'];
    });

    krsort($list);

    $sum  = 0;

    foreach ($list as $r)
    {
      $sum += $r['playtime_forever'];
      $rows[] = array(
        'name'   => $r['name'],
        'date'   => sprintf('%dh %dm', $r['playtime_forever'] / 60, $r['playtime_forever'] % 60),
      );
    }
  }

  function getApiResponse($url, $params = array())
  {
    return json_decode(file_get_contents($url.'?'.http_build_query($params)), true);
  }
?><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</head>
<body>
  <div class="container">
    <div class="row">
      <h2>ゲーム一覧</h2>
      <?php if ($key && $userid):?>
        <table class="table">
          <tr>
            <th>title</th>
            <th>time</th>
          </tr>
          <?php foreach ($rows as $row):?>
          <tr>
            <td><?php echo $row['name']?></td>
            <td><?php echo $row['date']?></td>
          </tr>
          <?php endforeach;?>
        </table>
      <?php else:?>
        <form method="post">
          <div class="form-group">
            <label class="control-label">Steam Web Api Key</label>
            <input type="" name ="key" pattern="^[0-9A-Z]+$" class="form-control" required="required" placeholder="API KEY">
          </div>
          <div class="form-group">
            <label class="control-label">Steam Id</label>
            <input type="" name ="userid" pattern="^[0-9]+$" class="form-control" required="required" placeholder="ID">
          </div>
          <div class="form-group">
              <button type="submit" class="btn btn-primary">Send</button>
          </div>
        </form>
      <?php endif;?>
    </div>
  </div>
</body>
</html>

APIキーとSteam idさえあれば、総プレイ時間とそれぞれのプレイ時間分かるようになっています。
こちらで、プレイ時間の偏りと、積みゲーの高さをお楽しみください。

まとめ

Steam Web APIを使うための準備と、簡単ではありますがそれを使ってみました。

ユーザの保有ゲームの一覧と、それぞれのプレイ時間を取得出来ましたが、既にこの時点での、私の積みゲーの多さにげんなりしてします。

さて次回ですが、ゲームごとの金額を取得しつつ積みゲーでどれだけ金を溝に捨てたのか、より優れたProSteamerであるかを分かるような調整を行おうと思います。