いぬと積みゲがとまらない

「ゲームは かならず プレイしてください! もっているだけじゃダメですよ!」

【GAS】SteamのWishListとPlayniteのライブラリを比較して重複を検出してみた話

はじめに

以下は、「Playniteを使っていて、かつSteamのウィッシュリストを整理したい人」に役に立つかもしれない記事です。
合致する人は少ないように思うけど、せっかくなので書き残したい。

概要としては、GASでスクリプトを作って、「Steam以外のプラットフォームで所有しているゲームがウィッシュリストに入っているか」をチェックしてみたよっていうお話。

自分用すぎるのでスクリプト公開はしてないけど、下記で作業の流れとソースを載せてるので、もしなにかの参考になれば……

経緯

  1. PCゲームについて、AmazonGames, EPIC, GOG, Steam を利用している  
  2. どのプラットフォームでどのゲームを所有しているのか分からなくなるのでPlayniteを使うようになる  
  3. 各プラットフォームのライブラリを一元化できたのは満足だが、Steamウィッシュリストについての機能はなさそう  
  4. Steamのウィッシュリストが1000件を超えていてはち切れそうなので、整理したい  
  5. まずは「他のプラットフォームで所有済みなのにSteamウィッシュリストに入りっぱなしのもの」を見つけたい  

膨大なウィッシュリストを上から見ていってPlayniteのライブラリにあるかな……なんて探してられないので、できる範囲での自動化を考えてみた。  

Steam以外のプラットフォームでゲームが配布されることも多くて、同じようなこと考えてる人いるとは思うんだけど、調べても見つからなかった。
Playnite本体にそういう拡張機能があったりしそうだが、ない模様。  

作業について

以下は、GASでスクリプトを実行して記事タイトルの目的を達成しようと試みた記録です。

作業後

こんな感じで、ウィッシュリスト内の「他のプラットフォームで所有済み」のタイトルが分かるようになりました。  

用意するもの

  • スプレッドシートにいくつかのシート

    • ウィッシュリストを取り込むシート(”SteamWishList”とする)
    • Playniteのライブラリを取り込むシート(”PlayniteLibrary”とする)  
    • ウィッシュリストJSONを貼り付けるシート(”PasteWishList”とする。別の手段で取り込むなら不要)
  • ウィッシュリストJSONデータ

    • Steamのウィッシュリストページを開き、ページのソースを表示
    • "g_rgWishlistData"で検索し、"=" の右側を全てコピーしてjsonファイルとして保存
    • ex. [{"appid":4000,"priority":0,"added":1450940468}, ... ];
    • もっと良い手段ないんか
  • PlayniteライブラリをCSV出力したもの

    • CSV出力してくれる拡張を使いました。→「Library Exporter Advanced」  
  • GASで実行するファイルを作成  

    • 今回は以下のようなファイルを作りました。  
    • importWishList.gs(ウィッシュリストをシートに取り込む処理)  
    • getAppTitle.gs(appidからゲームのタイトルを取得し、シートに反映する処理)  
    • removeSymbolWishList.gs(ウィッシュリストのゲームタイトルから記号を削除する処理)  
    • removeSymbolPlaynite.gs(Playniteライブラリのゲームタイトルから記号を削除する処理)  
    • duplicateCheck.gs(ゲームタイトルを比較し、重複を検知したりする処理)  

手順

  1. PlayniteLibraryシートに、用意したPlayniteライブラリのcsvをインポート  
  2. SteamWishListシートに、用意したウィッシュリストデータをインポート  
  3. getAppTitle.gs を実行し、Steam WebAPIからゲームタイトルを取得し、SteamWishListシートに反映  
    • ウィッシュリストが多い場合は、何回か実行。(GASの実行制限回避のため)
    • タイトル未取得のゲームが多い場合は、ちょっと時間かかります。
  4. 重複チェックの前に、タイトル文字列から記号など不要な文字を削除  
    • プラットフォームごとのタイトルの表記ブレを避けるため。  
    • 上記のremoveSymbol の2つを実行。  
  5. duplicateCheck.gs を実行し、ウィッシュリストとPlayniteライブラリで重複しているものを探す  

ソース

初めてGASで作ってみたけど、手軽にできて楽しかった。
「一回のスクリプト実行は6分以内の処理」という実行制限があるらしく、処理を小分けにすることを考える必要があった。

https://github.com/KK-kaito/SteamWishListChecker-GAS  

GASはググったら情報がいっぱい出てくるので良いですね。
とりあえず手軽に開発したくてGASにしたんだけど、他の方法でもっといい感じに目的を達成できないだろうか。

若干のソース説明など

  • importWishList.gs
    PasteWishList というウィッシュリストを貼るためだけのシートのA1セルにぺたっとJSONデータを貼っておいて、それをSteamWishListシートに取り込む感じ。
    すでにSteamWishListシートにあるappidは無視。なので初回取り込み時だけちょっと長いです。
    自分が動かしたときは980件くらいだったけど、それくらいだと6分以内には収まっていた。
    要するにシート上にウィッシュリスト内の全てのゲームタイトルがあればそれでOKなんだけど、自分の知っているウィッシュリスト一覧のテキストでの取得方法が上記のJSONしかないので、このような処理を書いた。
    ValveさんがウィッシュリストをWebAPIで返してくれればそれで終わりなので、つくってくれないかなあ。

  • getAppTitle.gs
    実行制限回避のため、一度に処理する件数を絞って使う想定。
    下記サイトを参考に、シートから取得したデータを扱う際に件数を絞るようにした。
    参考:https://zenn.dev/nag8/articles/6402d40066d912
    SteamWishListシートの"status"列を見て未実行なら処理対象で、WebAPIを叩いてゲームタイトルを取得する。
    WebAPIの規約を見ると、1日あたりのcallが制限されてるのは分かったんだけど、もう少し短い時間あたりの制限があるのかどうかは分からなかったので、とりあえず1秒に1回程度にしている。

    https://steamcommunity.com/dev/apiterms?l=japanese
    You are limited to one hundred thousand (100,000) calls to the Steam Web API per day.
    ユーザーは、Steam Web API を 1 日あたり 100,000 回呼び出すことができます。

    参考までに、処理時間は100件で約2分半とかです。
    おそらくこの記事で書いているような作業をしたい人は相当なウィッシュリスト数になっていると思うので、何回か実行する必要があるかと思います。
    なのでこれもまた、初回はちょっと時間かかります。

  • removeSymbolWishList.gs, removeSymbolPlaynite.gs
    他のプラットフォームでのゲームタイトル表記で、よく見ると若干の差異があることに気付いたので、比較用の文字列を作るための処理を噛ませることにした。
    参考:https://qiita.com/xryuseix/items/55b9e822e4a01247f25a
    そして、例によって実行制限回避のために2つにソースが分かれました。
    処理時間は大体5件で1秒といったところ。

  • duplicateCheck.gs
    SteamWishListシートとPlayniteLibraryシートのゲームタイトルを比較し、重複していればSteamWishListシートの該当セルの色を変える。
    こいつがやりたいがためにここまで準備している。
    ウィッシュリストから削除しやすいように、ストアページのURLも出力するようにしてます。
    特に理由がなければ、用事が済んだらSteamWishListシートの不要な行は削除したらいいかと思います。

  • appdetailsのWebAPIについて
    たまにappdetailsが返ってこないゲームもある。レスポンス自体が返ってこないパターン。
    ストアページ見に行くと普通にアクセスできる。
    原因はよく分からないし一時的なものかもしれない。そういうタイトルは「未実行」のままになるようにしている。
    レスポンスは返ってくるけどnameが取れないのは、多分ストアが消えてるとかだと思います。

  • 現時点で、すでに改善したほうが良いなあと思うとこがいくつか
    比較するために、記号の類は不要だと思ってゲームタイトルの文字列から削除してるんだけど、
    "&"とかゲームタイトルにつく可能性が高い記号は除外した方が良いかもしれない。
    例えば、「○○ I&II」というタイトルがあった場合、「○○ III」に変換されてしまうので、想定と異なる検知をする可能性あり。
    とりあえずの「Steamウィッシュリストと他プラットフォームライブラリとの重複」という目的が達成できて満足しちゃったので、直したり直さなかったりしようと思う。
    あと、カラム番号直書きするよりはヘッダー行を参照して取得するほうが良いかと思ったけど、列を入れ替えたりしても機能するかどうかはテストしてないのでバグってるかも。

余談   

  • 定期実行について
    思い立ったときにやればいい作業かなと考えているので、定期的に実行したりはしていない。
    材料として使っているSteamウィッシュリストデータとPlayniteライブラリのデータを自動的に出力できれば、GAS側も定期実行することで完全に自動化できて素敵だと思うけど、
    手動で用意してる以上はスクリプトも上からポチポチ実行してけば良いかな、って……

  • ウィッシュリストについて
    そもそもウィッシュリストをパンパンにするような生き方がよくないのかもしれない。
    もちろんやりたいゲームのリストではあるんだが、「アーリーアクセスなので様子見」だったり、
    安くなったからといってすぐに買いはしないけど、記憶しておきたいゲームのリストとしても使っているので、かなり軽い気持ちでウィッシュリストに放り込んでいる。
    すると、気づくと1000件を超えている。
    ウィッシュリストを追加日順に並べてみると、2012年に入れたものが未だに入っている。
    そして、そういうゲームをセール時に急に買ったりしている。
    さらに、ライブラリで数年寝かしたりしている。
    これからもそういう生き方をしていこうと思う。