【Steam】インベントリのアイテムをスタックしてまとめる方法

PCゲーム

Steamのインベントリを整理するためにアイテムをスタックする方法を調べたので共有します。

この方法を使えば、Steamのジェム(Gem)BananaRustCS2のアイテムなどで同じものをまとめてインベントリをすっきりさせることが出来ます。

Steamのアイテムをスタックする手順

ブラウザでSteamにログインする

スタックを始めるためには、まずSteamにブラウザでログインします。
ブラウザの種類に指定はありませんが、今回は Google Chrome で説明します。

また、Steam関連のプラグイン (Steam Inventory Helper など) が有効になっている場合は、一度無効にするようにしてください。

スタック用のスクリプトをコピーする

スタック用のスクリプトをコピーします。

スクリプトは先人がGithubで公開してくれたものがあるので、コピーして使いましょう。

以下のリンクにある StackAllItemsForAppid.js がスタック用のスクリプトです。

GitHub - steamnerds/userscripts
Contribute to steamnerds/userscripts development by creating an account on GitHub.

念のため、この記事内にも同じものを残しておきます。

(() => {
  if (!/^https:\/\/steamcommunity\.com\/(id\/[\w-_]{1,64}|profiles\/\d{17})\/inventory/.test(location.href)) {
    console.error("You need to run this script on your inventory page");
    return false;
  }

  var [appid, context, webapikey, sleep, invDesc, invAssets, classidsToCombine] = [location.hash.substr(1).replace(/\D/g, ''), '', '', '', '', '', {}];
  appid = appid != '' ? appid : '753';
  ShowPromptDialog("Please enter the appid", "", "Continue", "Abort", '', appid).done((a) => {
    appid = a;
    let text = 'Here are the available context number for this app (usually only the number 2):<br><br>';
    for (var contextnr in g_rgAppContextData[appid].rgContexts) {
      if (g_rgAppContextData[appid].rgContexts.hasOwnProperty(contextnr)) {
        text += contextnr + ': ' + g_rgAppContextData[appid].rgContexts[contextnr].name + ' (' + g_rgAppContextData[appid].rgContexts[contextnr].asset_count + ')<br>';
      }
    }
    text += '<br>';
    ShowPromptDialog("Please enter the correct context number", text, "Continue", "Abort", '', '2').done((b) => {
      context = b;
      ShowPromptDialog("Please enter your Steam WebAPIkey", 'Enter the key listed here: <a href="https://steamcommunity.com/dev/apikey">https://steamcommunity.com/dev/apikey</a> <br><br>', "Continue", "Abort", '', '').done((c) => {
        webapikey = c;
        ShowPromptDialog("Time to sleep between api calls (in ms)", "", "Run", "Abort", '', '1000').done((d) => {
          sleep = d;
          invDesc = g_rgAppContextData[appid].rgContexts[context].inventory.m_rgDescriptions;
          invAssets = g_rgAppContextData[appid].rgContexts[context].inventory.m_rgAssets;
          //	console.log([appid, context, webapikey, sleep, invDesc, invAssets, classidsToCombine]);
          stackItems();
        });
      });
    });
  });

  document.location.href = document.location.href.split('#')[0] + "#" + appid;

  // Used function (GoToPage) from Augmented Steam browser extension by mistake, should work without it now.
  //g_ActiveInventory.GoToPage(g_ActiveInventory.m_cPages);


  async function stackItems() {
    ShowAlertDialog("Stacking items", '<div id="itemstacking"></div>');
    var key;
    var itemToPush = {};
    for (key in invDesc) {
      if (invDesc[key].use_count > 1) {
        //console.log("classid '" + invDesc[key].classid + "' has " + invDesc[key].use_count + " counts.");
        var classidToPush = {
          name: invDesc[key].name,
          type: invDesc[key].type,
          use_count: invDesc[key].use_count,
          classid: parseInt(invDesc[key].classid),
          items: []
        };
        classidsToCombine[invDesc[key].classid] = classidToPush;

      }
    }

    for (key in invAssets) {
      if (classidsToCombine.hasOwnProperty(invAssets[key].classid)) {
        itemToPush = {
          //appid: invAssets[key].appid,
          //contextid: invAssets[key].contextid,
          assetid: invAssets[key].assetid,
          classid: invAssets[key].classid,
          //instanceid: invAssets[key].instanceid,
          amount: invAssets[key].amount,
          //is_currency: invAssets[key].is_currency,
          original_amount: invAssets[key].original_amount
          //is_stackable: invAssets[key].is_stackable
        };
        classidsToCombine[invAssets[key].classid].items[invAssets[key].assetid] = itemToPush;
      }
    }
    //console.log(classidsToCombine);

    var readyToCombine = {};
    for (key in classidsToCombine) {
      readyToCombine[classidsToCombine[key].classid] = [];
      for (var item in classidsToCombine[key].items) {
        if (classidsToCombine[key].items[item].hasOwnProperty("assetid")) {
          classid = classidsToCombine[key].items[item].classid;
          assetid = classidsToCombine[key].items[item].assetid;

          itemToPush = {
            assetid: classidsToCombine[key].items[item].assetid,
            amount: classidsToCombine[key].items[item].amount
          };

          //console.log(classidsToCombine[key]["items"][item]);
          //console.log(classidsToCombine[key]["items"][item].assetid);
          readyToCombine[classid].push(itemToPush);
        }
      }
    }
    //console.log(readyToCombine);

    if (Object.keys(readyToCombine).length == 0) {
      $J('#itemstacking').text('No items to stack');
    }
    for (key in readyToCombine) {
      for (i = 1; i < readyToCombine[key].length; i++) {
        //console.log(readyToCombine[key][i]);
        $J('#itemstacking').text('Stacking items: ' + i + '/' + (readyToCombine[key].length - 1));

        var url = "https://api.steampowered.com/IInventoryService/CombineItemStacks/v1/?key=" + webapikey +
          "&appid=" + appid + "&fromitemid=" + readyToCombine[key][i].assetid + "&destitemid=" + readyToCombine[key][0].assetid + "&quantity=" + readyToCombine[key][i].amount;
        var othePram = {
          headers: {
            "content-type": "application/json; charset=UTF-8"
          },
          method: "POST",
          mode: "no-cors"
        };


        //console.log("url: " + url);

        fetch(url, othePram)
          .then(data => {
            console.log(data);
            return data.json;
          })
          .catch(error => console.log(error));

        await new Promise(r => setTimeout(r, sleep));
      }
      $J('#itemstacking').text('Stacking items complete');
    }
  }
})();

スクリプトを実行する

Steamの上部メニューから、 [ユーザー名] > [インベントリ] を開きます。

インベントリの中からスタックしたいインベントリを選び、最後のページまで移動します。

[F12]キーを押下し、ブラウザのデベロッパーツールを開きます。

デベロッパーツールのメニューから [コンソール] を開き、先ほどコピーしたスクリプトを張り付けてエンターを押下します。

すると、以下のようなポップアップが表示されます。
自動的に現在開いているインベントリの appid が取得されているので、Continue をクリックします。

次に以下のポップアップが表示されます。
記載されている通り基本的には 2 が使われているため、特に変更せず Continue をクリックします。

次に WebAPIKey を入力することを求められます。
これは、 API を使ってインベントリアイテムのやり取りをするために必要になります。

そのため、API Key を有効化するために表示されているURLを右クリックし、「新しいタブ」か「新しいウィンドウ」で開きます。

URLを開くと、 Steam Web API キー登録のページが開きます。
ドメイン名に適当な文字列を入力します。(自分が判別するための一時的なものなので本当になんでも良いです)
利用規約の同意をチェックし、登録をクリックします。

この時、Steamガードを導入している場合は以下のように認証を求められるので、ご自身が利用している方法 (アプリやメール) から認証を行います。

認証が完了するとキーが登録されるので、キーの値をコピーします。
最後に無効化することを推奨するので、ページは開いたままにしてください。
※このキーが漏れると、Steamのアカウントにやりたい放題出来てしまうので注意しましょう

ポップアップが出ていたページに戻り、先ほどコピーしたキーの値をペーストして Continue をクリックします。

次に API を呼び出す間隔の設定です。
デフォルトは1000msになっていますが、100msまでなら正常に動作するようなので100に変更して Run をクリックします。

するとスタックの処理が始まります、すべてが完了すると「 Stacking items complete 」と表示されるので、 OK をクリックして完了になります。

最後に先ほどキーを作成したページに戻り、「 Steam Web API キーを無効にする」をクリックしてキーを無効化します。

逆にアイテムを1つずつに分けたい場合は、先ほど紹介した Github にあるSplitAllItemsForAppid.jsを使えば、同様の手順で可能です。

以上。

タイトルとURLをコピーしました